Bash脚本错误:在寻找匹配的“''

时间:2016-07-09 19:04:39

标签: bash macos shell

我试图运行这个shell脚本,但是我收到了错误:

  在寻找匹配的'''

时出现意外的EOF

  

语法错误:意外的文件结尾

当我将.asd /'切换为.asd /'时没有错误。但似乎没有任何事情发生。该脚本的目标是告诉我/ Music中的哪些音乐文件没有相应的.asd文件。脚本是:

#!/bin/bash
files=`mdfind -onlyin ~/Music “kMDItemUserTags==Green” | sed -E -e 's/\.[a-zA-Z1-3]+$/.asd/‘`
for aFile in $files 
do
    if [ ! -e $aFile ]; then
        echo $aFile;
    fi
done

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:4)

补充Alex Ives's helpful answer

shellcheck.net对语法检查shell脚本的赞美已被多次演唱,并且理所当然:

如果我们将您的脚本粘贴到那里(在将管道拆分为2行以便于阅读)之后,我们会得到(此处省略了附加的附带消息,但在下面进一步列出):

Line 2:
files=`mdfind -onlyin ~/Music “kMDItemUserTags==Green” | 
                              ^-- SC1015: This is a unicode double quote. Delete and retype it.
                                                     ^-- SC1015: This is a unicode double quote. Delete and retype it.

Line 3:
  sed -E -e 's/\.[a-zA-Z1-3]+$/.asd/‘`
                                    ^-- SC1016: This is a unicode single quote. Delete and retype it.

正如您所看到的,shellcheck.net已经确定了您的问题,并且还提供了以下指示:

Line 2:
files=`mdfind -onlyin ~/Music “kMDItemUserTags==Green” | 
      ^-- SC2006: Use $(..) instead of legacy `..`.

Line 6:
    if [ ! -e $aFile ]; then
              ^-- SC2086: Double quote to prevent globbing and word splitting.

Line 7:
        echo $aFile;
             ^-- SC2086: Double quote to prevent globbing and word splitting.

此外,您不应使用for枚举文件名,因为这会破坏带有嵌入空格的文件名。

相反,请使用:

while IFS= read -r aFile; do
  # work with "$aFile"
done < <(mdfind -onlyin ~/Music ...)

William Pursell正确地在评论中指出IFS= read -r aFile失败,文件名包含换行符
也就是说,嵌入换行符的文件名很少是现实世界的关注点;相比之下,嵌入了空格的文件名是IFS= read -r aFile正确处理的情况。

答案 1 :(得分:2)

看起来你在mdfind里面有卷曲引号。卷曲引号的解释方式与直引号不同。因此,在用替换'时解决了文件结束错误,您可能无法与“kMDItemUserTags==Green”匹配任何内容。尝试将其替换为"kMDItemUserTags==Green",看看是否有效。

单引号发生的事情是它匹配第一个而不是第二个,所以当你得到结束引用(卷曲)时,它一直认为它是引用字符串的一部分,并一直读到结束时档案(EOF)。

希望有所帮助!