4

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

例如,考虑这种情况:

ls | grep Hello

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

非常感谢你的帮助!

4

2 回答 2

9

grep本身将被构建,如果您没有指定文件名,它将打开标准输入(并因此获得 的输出ls)。这里没有真正的通用机制——只是约定。

如果您希望输出 ofls作为搜索词,您可以通过 shell 执行此操作。因此使用子shell和替换

$ grep $(ls) filename.txt

在这种情况下ls,在子 shell 中运行,它的标准输出被捕获并作为grep. 请注意,如果ls输出包含空格,这将导致grep.

于 2013-01-17T16:24:45.880 回答
7

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

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

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

ls | xargs grep -- term

搜索lsfor输出的所有文件term。当然,如果您只想要当前目录中的文件,您可以更简单地无需管道:

grep -- term *

同样在你相反的安排中,

for filename in *; do
  grep -- "$@" PathOfFileToBeSearched
done

有一个重要的xargs警告:生成的文件名中的空白字符ls不会得到很好的处理。为此,只要您有 GNU 实用程序,您就可以使用它find

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

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

于 2013-01-17T16:40:11.347 回答