使用 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=]
的虚拟占位符。)
当我在终端中运行这个命令时:
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=]
的虚拟占位符。)