bash脚本中意外标记“do”附近的语法错误

时间:2016-05-11 01:30:58

标签: bash unix ffmpeg

我有bash脚本,它从命令行获取3个参数。它会比较目录中的所有文件,以查看它们是否属于前2个参数的类型。如果是,则脚本使用FFMPEG命令将此类文件转换为第三个参数的类型。我将使用以下命令执行脚本:

./convert.sh .avi .mp4 .flv 

这样,这个脚本会将所有.avi和.mp4文件转换为.flv。

当我运行脚本时,我收到错误

syntax error near unexpected token `do' in bash script.

以下是代码:

#!/bin/bash

# $1 is the first parameter passed
# $2 is the second parameter passed 
# $3 is the third parameter passed

for file in *.*; 
    do 
        #comparing the file types in the directory to the first 2 parameters passed
        if[  ( ${file: -4} == "$1" ) || ( ${file: -4 } == "$2" )  ]{
            export extension=${file: -4}
            #converting such files to the type of the first parameter using the FFMPEG comand
            do ffmpeg -i "$file" "${file%.extension}"$3;
done

5 个答案:

答案 0 :(得分:3)

这里有一堆语法错误。让我们从这一行开始:

if[  ( ${file: -4} == "$1" ) || ( ${file: -4 } == "$2" )  ]{
  • 您需要if[之间的空格(或其后的任何内容)。如上所述,shell正在将“if [”视为命令的名称,而这根本不是您想要的。

  • 条件的[ ... ]样式不理解||(它使用-o代替),要求所有shell元字符(如括号)被转义或引用,可能不理解==(仅=是标准的),如果任何未加引号的变量/参数引用为空,则会非常困惑。

  • if条件以then结尾(在下一行,或;之后){

你可以这样解决:

if [  \( "${file: -4}" = "$1" \) -o \( "${file: -4}" = "$2" \) ]; then

或者,由于您使用的是bash(而不是更基本的shell),因此您可以使用[[ ... ]]条件样式,它具有更清晰的语法:

if [[ "${file: -4}" = "$1" || "${file: -4}" = "$2" ]]; then

接下来,删除do之前的ffmpegdoforwhile循环语法的一部分;你已经拥有一个(它属于它),而这个没有意义。这就是导致你看到错误的原因。

接下来,您更换文件扩展名的方式无效。变量引用"${file%.extension}"$3将尝试从$file的末尾删除“.extension”(不是变量,只是字符串)。它在引号之外也有$3,这可能会带来麻烦。您可以使用"${file%$extension}$3"来修复此问题,但坦率地说,我只需使用"${file%.*}$3"删除扩展名,无论它的长度是多少(我也会同样重做if次比较,但那更复杂了。)

最后,您需要fi(在ffmpeg行之后)来结束条件。每个if都需要thenfi

就像风格一样,你在shell的一行末尾不需要;;只有在将多个命令(或dothen之类的东西)放在同一行上时才需要它。无论如何,这是我的快速重写:

#!/bin/bash

# $1 is the first parameter passed
# $2 is the second parameter passed 
# $3 is the third parameter passed

for file in *.*; do
    #comparing the file types in the directory to the first 2 parameters passed
    if [[  "${file: -4}" = "$1" || "${file: -4}" = "$2"  ]]; then
        #converting such files to the type of the first parameter using the FFMPEG comand
        ffmpeg -i "$file" "${file%.*}$3"
    fi
done

答案 1 :(得分:2)

对我来说,这是由于CRLF造成的。对于Linux env,它应该为LF

答案 2 :(得分:1)

您的脚本可以简化为:

#!/bin/bash

for file in *; do
    [[ ${file: -4} = $1 || ${file: -4} = $2 ]] && ffmpeg -i "$file" "${file%.*}$3"
done

答案 3 :(得分:1)

即使我也遇到了同样的错误。 [https://i.stack.imgur.com/PsWGF.png]->此链接将带您到错误消息。

下面的链接中提供了使我遇到此消息的代码。 [https://i.stack.imgur.com/Wom7q.png]

如果您观察到与 do 命令相关的错误,则会出现有关while语法的错误。您可以通过在方括号内插入空格来消除该错误。 [https://i.stack.imgur.com/F1C7x.png]

这是由于 [不是内置的 shell 而是接收表达式作为参数的事实。如果 [”没有用空格包围,则解释器会将其解释为$ PATH。

我希望这个答案可以帮助您解决问题。

答案 4 :(得分:0)

您的格式和语法存在一些问题。 sjsam建议使用shellcheck是好的,但简短的版本是你应该在if语句的内部括号上使用方括号而不是圆括号:

if [ ${file: -4} == "$1" ] || [ ${file: -4 } == "$2" ] {

我认为你的ffmpeg线或上面一行末尾的花括号之前你不需要'do',所以你最终得到......

for file in *.*; 
    do 
    #comparing the file types in the directory to the first 2 parameters passed
    if [  ${file: -4} == "$1" ] || [ ${file: -4 } == "$2" ]
        export extension=${file: -4}
        #converting such files to the type of the first parameter using the FFMPEG comand
        ffmpeg -i "$file" "${file%.extension}"$3;
    fi
done