我正在尝试使用两个不同的可执行文件构造一个find命令来处理目录中的一堆文件。不幸的是,-exec
on find不允许使用管道甚至\|
,因为shell首先解释该字符。
这是我正在尝试做的事情(由于管道结束了find命令,因此无效):
find /path/to/jpgs -type f -exec jhead -v {} | grep 123 \; -print
答案 0 :(得分:77)
试试这个
find /path/to/jpgs -type f -exec sh -c 'jhead -v {} | grep 123' \; -print
或者你可以尝试将你的exec语句嵌入到sh脚本中,然后执行:
find -exec some_script {} \;
答案 1 :(得分:11)
稍微不同的方法是使用xargs:
find /path/to/jpgs -type f -print0 | xargs -0 jhead -v | grep 123
我总是觉得更容易理解和适应(-print0和-0参数是处理包含空格的文件名所必需的)
这个可能(未经测试)比使用-exec更有效,因为它会将文件列表传递给xargs,并且xargs确保jhead命令行不会太长。
答案 2 :(得分:3)
使用-exec
,您只能使用一些参数运行单个可执行文件,而不是任意shell命令。为了避免这种情况,您可以使用sh -c '<shell command>'
。
请注意,使用-exec
的效率非常低。对于找到的每个文件,必须再次执行该命令。如果你能避免这种情况会更有效率。 (例如,将grep
移到-exec
之外,或按Palmin的建议将find
的结果移至xargs
。)
答案 3 :(得分:3)
对这种类型的任务使用find
命令可能不是最佳选择。我经常使用以下命令查找包含所请求信息的文件:
for i in dist/*.jar; do echo ">> $i"; jar -tf "$i" | grep BeanException; done
答案 4 :(得分:1)
因为这会输出一个列表,你不会:
find /path/to/jpgs -type f -exec jhead -v {} \; | grep 123
或
find /path/to/jpgs -type f -print -exec jhead -v {} \; | grep 123
将grep放在find -exec的结果上。
答案 5 :(得分:0)
你可以采取另一种方式,但它也是非常贫穷的。
使用shell选项extquote你可以做类似的事情,以便查找exec的东西,然后将它传递给sh。
root@ifrit findtest # find -type f -exec echo ls $"|" cat \;|sh
filename
root@ifrit findtest # find -type f -exec echo ls $"|" cat $"|" xargs cat\;|sh
h
我只是觉得我要添加它,因为至少我可视化它的方式,它更接近OP在exec中使用管道的原始问题。