我正在寻找有关如何使用管道传递标准输出作为其他命令的参数的见解。
例如,考虑这种情况:
ls | grep Hello
grep的结构遵循以下模式:grep SearchTerm PathOfFileToBeSearched
。在我已经说明的情况下,将Hello一词视为SearchTerm
,并将ls的结果用作要搜索的文件。但是,如果我想切换它怎么办?如果我希望ls的标准输出为SearchTerm,并且grep之后的参数为PathOfFileToBeSearched
,该怎么办?在一般意义上,我想控制管道填充哪个参数与前一个命令的标准输出。这是可能的,还是取决于命令的脚本(例如grep
)是如何编写的?
非常感谢你的帮助!
答案 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字符分隔文件名而不是空格