用于命令参数的Unix管道

时间:2013-01-17 16:23:25

标签: unix io pipe

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

例如,考虑这种情况:

ls | grep Hello

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

非常感谢你的帮助!

2 个答案:

答案 0 :(得分:9)

grep本身将被构建,如果你没有指定文件名,它将打开stdin(从而获得ls的输出)。这里没有真正的通用机制 - 仅仅是惯例。

如果您希望ls的输出成为搜索词,可以通过shell执行此操作。使用子shell和substitution因此:

$ grep $(ls) filename.txt

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

答案 1 :(得分:7)

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

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

对于ls输出的每个文件,它将运行grep -e filename PathOfFileToBeSearched grep,以便在您指定的另一个文件中ls输出文件名。这是一个不寻常的xargs调用;通常它用于在命令末尾添加一个或多个参数,而在这里它应该在特定位置添加一个参数,所以我使用了-n和{{1}用于安排的参数。更常见的用法是

-J

搜索ls | xargs grep -- term ls输出的所有文件。虽然当然如果你只想要当前目录中的文件,你可以更简单地没有管道:

term

同样在你的反向安排中,

grep -- term *

有一个重要的for filename in *; do grep -- "$@" PathOfFileToBeSearched done 警告:由xargs生成的文件名中的空白字符不会被处理得太好。为此,如果您有GNU实用程序,则可以使用ls代替。

find

使用NUL字符分隔文件名而不是空格