意外标记“fi”附近的语法错误

时间:2021-11-12 01:04:41

I'm trying to write a script that removes all the .jpg's that end in an odd number. This is my code:

我试着写一个脚本,删除所有的。jpg,以一个奇数结尾。这是我的代码:

#!/bin/bash
echo "start\n"
for f in *.jpg
do
  fname=$(basename "$f")
  echo "fname is $fname\n"
  fname="${filename%.*}"
  echo "fname is $fname\n"
  if[$((fname %  2)) -eq 1 ] then
    echo "removing $fname\n"
    rm $f
  fi
done

When I run it it outputs start and then says "syntax error near unexpected token 'fi'"

当我运行它时,它会输出启动,然后说“在意料之外的标记‘fi’附近的语法错误”

When I had then on the line after if it said "syntax error near unexpected token 'then'"

当我在这条线上的时候,如果它说"语法错误,在意料之外的标记'然后'"

How do i fix this?

我怎么解决这个问题?

4 个解决方案

#1


45  

As well as having then on a new line, you also need a space before and after the [, which is a special symbol in BASH.

除了在新行上使用外,您还需要在[在BASH中是一个特殊符号]之前和之后的空间。

#!/bin/bash
echo "start\n"
for f in *.jpg
do
  fname=$(basename "$f")
  echo "fname is $fname\n"
  fname="${filename%.*}"
  echo "fname is $fname\n"
  if [ $((fname %  2)) -eq 1 ]
  then
    echo "removing $fname\n"
    rm "$f"
  fi
done

#2


10  

Use Notepad ++ and use the option to Convert the file to UNIX format. That should solve this problem.

使用Notepad ++并使用选项将文件转换为UNIX格式。这应该能解决这个问题。

#3


3  

"Then" is a command in bash, thus it needs a ";" or a newline before it.

“然后”是bash中的命令,因此它需要一个“;”或在它之前的换行。

#!/bin/bash
echo "start\n"
for f in *.jpg
do
  fname=$(basename "$f")
  echo "fname is $fname\n"
  fname="${filename%.*}"
  echo "fname is $fname\n"
  if [$[fname%2] -eq 1 ]
  then
    echo "removing $fname\n"
    rm $f
  fi
done

#4


3  

The first problem with your script is that you have to put a space after the [.
Type type [ to see what is really happening. It should tell you that [ is an alias to test command, so [ ] in bash is not some special syntax for conditionals, it is just a command on its own. What you should prefer in bash is [[ ]]. This common pitfall is greatly explained here and here.

您的脚本的第一个问题是您必须在[。键入类型[查看实际发生的情况]。它应该告诉您,[是测试命令的别名,所以[]在bash中不是用于条件的特殊语法,它只是自己的命令。在bash中您应该更喜欢[[]]。这个常见的陷阱在这里和这里有很大的解释。

Another problem is that you didn't quote "$f" which might become a problem later. This is explained here

另一个问题是,您没有引用“$f”,以后可能会出现问题。这是解释

You can use arithmetic expressions in if, so you don't have to use [ ] or [[ ]] at all in some cases. More info here

您可以在if中使用算术表达式,因此您不必在某些情况下使用[]或[[]]。更多的信息在这里

Also there's no need to use \n in every echo, because echo places newlines by default. If you want TWO newlines to appear, then use echo -e 'start\n' or echo $'start\n' . This $'' syntax is explained here

同样,在每个echo中也不需要使用\n,因为echo会默认设置新行。如果您想要出现两个新行,那么使用echo -e 'start\n'或echo $'start\n'。这里解释了这个$“语法”。

To make it completely perfect you should place -- before arbitrary filenames, otherwise rm might treat it as a parameter if the file name starts with dashes. This is explained here.

要使它完全完美,您应该在任意文件名之前放置——否则,如果文件名以dashes开头,rm可以将其视为参数。这是解释说。

So here's your script:

这是你的脚本:

#!/bin/bash
echo "start"
for f in *.jpg
do
    fname="${f##*/}"
    echo "fname is $fname"
    if (( fname % 2 == 1 )); then
        echo "removing $fname"
        rm -- "$f"
    fi
done

#1


45  

As well as having then on a new line, you also need a space before and after the [, which is a special symbol in BASH.

除了在新行上使用外,您还需要在[在BASH中是一个特殊符号]之前和之后的空间。

#!/bin/bash
echo "start\n"
for f in *.jpg
do
  fname=$(basename "$f")
  echo "fname is $fname\n"
  fname="${filename%.*}"
  echo "fname is $fname\n"
  if [ $((fname %  2)) -eq 1 ]
  then
    echo "removing $fname\n"
    rm "$f"
  fi
done

#2


10  

Use Notepad ++ and use the option to Convert the file to UNIX format. That should solve this problem.

使用Notepad ++并使用选项将文件转换为UNIX格式。这应该能解决这个问题。

#3


3  

"Then" is a command in bash, thus it needs a ";" or a newline before it.

“然后”是bash中的命令,因此它需要一个“;”或在它之前的换行。

#!/bin/bash
echo "start\n"
for f in *.jpg
do
  fname=$(basename "$f")
  echo "fname is $fname\n"
  fname="${filename%.*}"
  echo "fname is $fname\n"
  if [$[fname%2] -eq 1 ]
  then
    echo "removing $fname\n"
    rm $f
  fi
done

#4


3  

The first problem with your script is that you have to put a space after the [.
Type type [ to see what is really happening. It should tell you that [ is an alias to test command, so [ ] in bash is not some special syntax for conditionals, it is just a command on its own. What you should prefer in bash is [[ ]]. This common pitfall is greatly explained here and here.

您的脚本的第一个问题是您必须在[。键入类型[查看实际发生的情况]。它应该告诉您,[是测试命令的别名,所以[]在bash中不是用于条件的特殊语法,它只是自己的命令。在bash中您应该更喜欢[[]]。这个常见的陷阱在这里和这里有很大的解释。

Another problem is that you didn't quote "$f" which might become a problem later. This is explained here

另一个问题是,您没有引用“$f”,以后可能会出现问题。这是解释

You can use arithmetic expressions in if, so you don't have to use [ ] or [[ ]] at all in some cases. More info here

您可以在if中使用算术表达式,因此您不必在某些情况下使用[]或[[]]。更多的信息在这里

Also there's no need to use \n in every echo, because echo places newlines by default. If you want TWO newlines to appear, then use echo -e 'start\n' or echo $'start\n' . This $'' syntax is explained here

同样,在每个echo中也不需要使用\n,因为echo会默认设置新行。如果您想要出现两个新行,那么使用echo -e 'start\n'或echo $'start\n'。这里解释了这个$“语法”。

To make it completely perfect you should place -- before arbitrary filenames, otherwise rm might treat it as a parameter if the file name starts with dashes. This is explained here.

要使它完全完美,您应该在任意文件名之前放置——否则,如果文件名以dashes开头,rm可以将其视为参数。这是解释说。

So here's your script:

这是你的脚本:

#!/bin/bash
echo "start"
for f in *.jpg
do
    fname="${f##*/}"
    echo "fname is $fname"
    if (( fname % 2 == 1 )); then
        echo "removing $fname"
        rm -- "$f"
    fi
done