我试图运行这个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
提前感谢您的帮助。
答案 0 :(得分:4)
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
)。
希望有所帮助!