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

Syntax error when using find and sh -c

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

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 有关,但我不知道如何解决它,谢谢。

./(terrible filename).png: PNG image data, 512 x 512, // trying to get this result

文件名中有括号吗?这可能有帮助:

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

您基本上是将文件名粘贴到 sh -c '...' 中而没有任何引号。 sh -c after find 替换后的字符串必须是有效的 sh 语法,这意味着不能有不带引号的单引号、括号等

一种更稳健的方法是使用 -exec file {} 并将所有输出从 find 传递到 egrep

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

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

(正如在对其他答案的评论中指出的那样,-exec sh -c 'file ""' _ {} \; 是实现该目标的另一种方法;这可以概括为任意复杂的 shell 命令。如果您的 find 支持 exec {} \+ 你想添加一个简单的循环: -exec sh 'for f; do file "$f"; done' _ {} \+ -- 顺便说一下, _[=26=] 的虚拟占位符。)