2013-01-17 154 views
3

我在寻找有关如何使用管道将标准输出作为其他命令的参数传递的见解。用于命令参数的Unix管道

例如,考虑这种情况:

ls | grep Hello 

的grep的结构遵循模式:grep SearchTerm PathOfFileToBeSearched。在我已经说明的情况下,词语Hello被视为SearchTerm,ls的结果被用作要搜索的文件。但是如果我想切换它呢?如果我希望ls的标准输出是SearchTerm,那么grep后面的参数是PathOfFileToBeSearched?在一般意义上,我想要控制管道填充上一个命令的标准输出的参数。这是可能的,还是取决于如何编写命令的脚本(例如,grep)?

非常感谢您的帮助!

回答

7

基本上有两种选择:shell命令替换和xargs。 Brian Agnew刚才写到前者。 xargs是一个实用程序,它将stdin转换为要执行的命令的参数。所以,你可以运行

ls | xargs -n1 -J % grep -- % PathOfFileToBeSearched 

,它将,由ls每个输出文件,运行grep -e filename PathOfFileToBeSearched通过ls您指定的其他文件中到grep的文件名输出。这是一个不寻常的调用;通常用于在命令末尾添加一个或多个参数,而在此应该在特定位置添加一个参数,所以我使用-n-J参数来排列该参数。比较常见的用法是像

ls | xargs grep -- term 

lsterm搜索所有的文件输出。虽然,当然,如果你只是想在当前目录下的文件,您可以在此更简单地没有管道:

grep -- term * 

,同样在颠倒配置,

for filename in *; do 
    grep -- "[email protected]" PathOfFileToBeSearched 
done 

还有一个重要xargs警告:空白由ls生成的文件名中的字符将不会被处理得太好。要做到这一点,只要你有GNU工具,你可以用find来代替。

find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 -n1 -J % grep -- % PathOfFileToBeSearched 

使用NUL字符分隔的文件名,而不是空白

8

grepgrep本身将被构建,使得如果你没有指定文件名,它将打开标准输入(从而得到输出ls)。这里没有真正的通用机制 - 仅仅是约定。

如果您想将ls的输出作为搜索词,您可以通过shell执行此操作。利用一个子shell的和substitution从而:

$ grep $(ls) filename.txt 

在这种情况下ls在一个子shell运行,并且它的标准输出被捕获并在命令行作为grep参数插入。请注意,如果ls输出包含空格,则会导致grep混淆。