我正在做一个find然后获取文件列表.如何将其传输到另一个实用程序cat(以便cat显示所有这些文件的内容),并且基本上需要grep从这些文件中获取内容.
ken*_*418 320
管道到另一个过程(虽然这不会完成你所说的你想要做的事情):
command1 | command2
Run Code Online (Sandbox Code Playgroud)
这将发送command1的输出作为command2的输入
-exec在a find(这将做你想做的事 - 但具体到find)
find . -name '*.foo' -exec cat {} \;
Run Code Online (Sandbox Code Playgroud)
(之间的一切find,并-exec在查找谓词你已经在使用, {}将取代你发现到命令的特定文件(cat {}在这种情况下);该\;是结束-exec.命令)
将一个进程的输出作为命令行参数发送到另一个进程
command2 `command1`
Run Code Online (Sandbox Code Playgroud)
例如:
cat `find . -name '*.foo' -print`
Run Code Online (Sandbox Code Playgroud)
(注意这些是BACK-QUOTES而不是常规引号(在我的键盘上的tilde~下).)这会将输出发送command1到command2命令行参数.但请注意,包含空格(换行符等)的文件名将被分解为单独的参数.
Jon*_*ler 82
find . -exec grep something {} +
Run Code Online (Sandbox Code Playgroud)
如果你在Linux或有GNU +和find,然后用xargs用xargs,并-0具有-0处理包含空格和其他奇数球字符的文件名.
如果你不想要文件名 - 只是文本 - 那么添加一个合适的选项xargs(通常是-r为了抑制'标题').要绝对保证文件名是打印的--no-run-if-empty(即使只找到一个文件,或者最后一次调用find只给出1个文件名),然后添加xargs到-print0命令行,这样总会至少有两个文件名.
请注意,POSIX 2008添加了find标记,-0这意味着它现在可以自动将尽可能多的文件分组到单个命令执行中,非常类似xargs,但具有许多优点:
这两个都是grep没有grep选项的问题.因此,你可以明智地写:
find . -print | xargs grep something
Run Code Online (Sandbox Code Playgroud)
Lau*_*ves 34
有几种方法可以将find命令返回的文件列表传递给cat命令,虽然技术上并非全部都使用管道,但实际上没有一个直接管道cat.
最简单的是使用反引号(`):
cat `find [whatever]`
Run Code Online (Sandbox Code Playgroud)
这需要输出find并有效地将其放在命令行上cat.如果find输出太多(超过可以放在命令行上)或者输出有特殊字符(如空格),则这不能很好地工作.
在某些shell中,包括bash,可以使用$()而不是反引号:
cat $(find [whatever])
Run Code Online (Sandbox Code Playgroud)
这不太便携,但可以嵌套.除此之外,它与反引号几乎有相同的警告.
因为在找到的内容上运行其他命令是常用的find,所以find有一个-exec动作,它为它找到的每个文件执行一个命令:
find [whatever] -exec cat {} \;
Run Code Online (Sandbox Code Playgroud)
它{}是文件名的占位符,\;标记命令的结尾(之后可能有其他操作-exec.)
这将为cat每个单个文件运行一次,而不是运行单个cat传递多个文件名的实例,这可能效率低下,并且可能没有您想要的某些命令的行为(尽管它很好cat).语法也是一个笨拙的类型 - 你需要转义分号,因为分号对shell来说是特殊的!
的某些版本find(最引人注目的是GNU版本)让你更换;与+使用-exec的追加模式下运行的更少的情况下cat:
find [whatever] -exec cat {} +
Run Code Online (Sandbox Code Playgroud)
这会将多个文件名传递给每次调用cat,这样可以更有效.
但请注意,不保证使用单个调用.如果命令行太长,那么参数将分布在多个调用中cat.因为cat这可能不是什么大问题,但对于其他一些命令,这可能会以不合需要的方式改变行为.在Linux系统上,命令行长度限制非常大,因此与其他一些操作系统相比,拆分为多个调用非常少见.
经典/便携式方法是使用xargs:
find [whatever] | xargs cat
Run Code Online (Sandbox Code Playgroud)
xargs运行指定的命令(cat在本例中),并根据从stdin读取的内容添加参数.就像-exec用+,这将在必要时向上突破的命令行.也就是说,如果find产生太多输出,它将运行cat多次.正如前面关于-exec前面部分所述,有一些命令会导致此拆分可能导致不同的行为.请注意,使用xargs这样的文件名中的空格有问题,因为xargs只使用空格作为分隔符.
最强大,最便携,最有效的方法还使用xargs:
find [whatever] -print0 | xargs -0 cat
Run Code Online (Sandbox Code Playgroud)
该-print0标志告诉在文件名之间find使用\0(空字符)分隔符,并且该-0标志告诉xargs期望这些\0分隔符.这与-exec... +方法具有完全相同的行为,但更便携(但不幸的是更冗长).
要实现这一点(使用bash),我会这样做:
cat $(find . -name '*.foo')
Run Code Online (Sandbox Code Playgroud)
这被称为"命令替换",它默认剥离换行,这非常方便!
这里有更多的信息
对我来说听起来像shell脚本的工作:
for file in 'find -name *.xml'
do
grep 'hello' file
done
Run Code Online (Sandbox Code Playgroud)
或类似的东西
小智 5
这是我查找包含一些我感兴趣的内容的文件名的方法,只需一个 bash 行就可以很好地处理文件名中的空格:
find . -name \*.xml | while read i; do grep '<?xml' "$i" >/dev/null; [ $? == 0 ] && echo $i; done
Run Code Online (Sandbox Code Playgroud)