【问题标题】:Syntax error near unexpected token 'fi'意外标记“fi”附近的语法错误
【发布时间】:2014-01-02 10:03:31
【问题描述】:

我正在尝试编写一个脚本来删除所有以奇数结尾的 .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

当我运行它时,它会输出 start 然后说“意外标记 'fi' 附近的语法错误”

当我有then上线后如果它说“语法错误接近意外标记'then'”

我该如何解决这个问题?

【问题讨论】:

    标签: bash


    【解决方案1】:

    您的脚本的第一个问题是您必须在 [ 之后放置一个空格。
    键入type [ 以查看实际情况。它应该告诉你[test 命令的别名,所以bash 中的[ ] 不是条件句的特殊语法,它本身就是一个命令。在 bash 中你应该更喜欢 [[ ]]herehere 详细解释了这个常见的陷阱。

    另一个问题是您没有引用"$f",这可能会在以后成为问题。这是解释here

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

    也没有必要在每个echo 中使用\n,因为echo 默认放置换行符。如果您希望出现两个换行符,请使用 echo -e 'start\n'echo $'start\n' 。这个$''语法解释here

    为了使其完全完美,您应该将-- 放在任意文件名之前,否则rm 可能会将其视为文件名以破折号开头的参数。这是解释here

    这是你的脚本:

    #!/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
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 这解决了我的问题。正在将脚本从 Windows 机器移动到 linux。
      • 这对我来说效果很好,我使用EditPlus在windows上创建了一个sh,并使用cygwin运行它,转换为UNIX格式非常有用。
      • 在 Windows 上编写脚本并尝试在 Mac 上运行后也帮助了我。我使用 Sublime Text (View > Line Endings > Unix) 进行了转换。
      • 在 Windows 上编辑文件,在 WSL 上运行。这有帮助!
      • Notepad++ -> Config -> NewDocument -> Unix(LF) 并创建新文档。这对我有用
      【解决方案3】:

      除了将then 放在新行之外,还需要在[ 前后留一个空格,这是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
      

      【讨论】:

      • 它仍然给我“意外标记'then'附近的语法错误”
      • 我发布的代码在我自己的系统上运行没有任何错误。我只能通过删除if[ 字符之间的空格来重新创建您引用的错误。确保我描述的所有空间都到位。
      • 你忘了引用"$f"
      • 我只关注有问题的语法错误,但公平地说,我已经编辑了代码以包含这些引号。
      • 此特定错误是由于 'then' 不在新行上。还值得注意的是,在之后放置一个分号 (;
      【解决方案4】:

      "Then" 是 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
      

      【讨论】:

      • 就像我说的,当我有然后上线后如果它说“语法错误接近意外令牌'then'”
      • 它有另一个原因,这个脚本没有这样做。但是还有一个问题,$((…)) 试图执行“fname % 2”,这不是你想要的。我也纠正了这个问题。
      猜你喜欢
      • 1970-01-01
      • 2015-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多