使用find和sh -c时出现语法错误

时间:2015-12-29 10:08:16

标签: macos bash terminal find sh

当我在终端中运行此命令时:

find . -type f -name "*.png" -exec sh -c "file {} | egrep -o '^.*\d+,'" \;

如果文件名包含括号,我会收到此错误:

sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `file ./(terrible filename).png | egrep -o '^.*\d+,''

我知道它与sh -c有关,但我不知道如何修复它,谢谢。

  

./(可怕的文件名).png:PNG图像数据,512 x 512,   // trying to get this result

2 个答案:

答案 0 :(得分:4)

您基本上将文件名粘贴到sh -c '...',而不引用任何内容。在 sh -c所做的替换之后,find 中的字符串需要是有效的sh语法,这意味着不能有任何不带引号的单引号,圆括号等。

更强大的方法是使用-exec file {}并将find的所有输出传递给egrep

find . -type f -name "*.png" -exec file {} \; | egrep -o '^.*\d+,'

占位符令牌{}find替换为当前正在处理的文件名。当它是一个单独的令牌时,find可以传入任何文件名;但如果将其插入到更长的字符串中,例如shell命令,则需要确保以某种方式添加任何必要的引用等。这很麻烦,所以通常你会想找到一个你不需要这样做的解决方案。

(正如对其他答案的评论所指出的,-exec sh -c 'file "$1"' _ {} \;是实现这一目标的另一种方式;这可以推广到任意复杂的shell命令。如果你的find支持exec {} \+,你想要添加一个简单的循环:-exec sh 'for f; do file "$f"; done' _ {} \+ - 顺便说一句,_$0的虚拟占位符。)

答案 1 :(得分:0)

文件名中是否有括号?这可能会有所帮助:

find . -type f -name "*.png" -exec sh -c "file '{}' | egrep -o '^.*\d+,'" \;