我正在寻找有关如何使用管道传递标准输出作为其他命令的参数的见解.
例如,考虑这种情况:
ls | grep Hello
Run Code Online (Sandbox Code Playgroud)
grep的结构遵循以下模式:grep SearchTerm PathOfFileToBeSearched.在我已经说明的情况下,将单词Hello作为,SearchTerm并将ls的结果用作要搜索的文件.但是,如果我想切换它怎么办?如果我希望ls的标准输出为SearchTerm,并且grep之后的参数是PathOfFileToBeSearched什么?在一般意义上,我想控制管道填充哪个参数与前一个命令的标准输出.这是可能的,还是取决于命令脚本(例如grep)的编写方式?
非常感谢你的帮助!
grep本身将被构建,如果你没有指定文件名,它将打开stdin(从而得到输出ls).这里没有真正的通用机制 - 仅仅是惯例.
如果您希望输出为ls搜索词,则可以通过shell执行此操作.利用子shell和替换因此:
$ grep $(ls) filename.txt
Run Code Online (Sandbox Code Playgroud)
在这种情况下ls,在子shell中运行,并捕获其stdout并将其作为参数插入命令行grep.请注意,如果ls输出包含空格,这将导致混淆grep.
基本上有两种选择:shell命令替换和xargs.Brian Agnew刚刚写过关于前者的文章.xargs是一个实用程序,它接受stdin并将其转换为执行命令的参数.所以你可以跑
ls | xargs -n1 -J % grep -- % PathOfFileToBeSearched
Run Code Online (Sandbox Code Playgroud)
对于每个输出的文件,它会在你指定的另一个文件中ls运行grep -e filename PathOfFileToBeSearchedgrep以获取文件名输出ls.这是一个不寻常的xargs调用; 通常它用于在命令的末尾添加一个或多个参数,而在这里它应该在特定的地方添加一个参数,所以我使用-n和-J参数来安排它.更常见的用法是类似的
ls | xargs grep -- term
Run Code Online (Sandbox Code Playgroud)
搜索lsfor 输出的所有文件term.虽然当然如果你只想要当前目录中的文件,你可以更简单地没有管道:
grep -- term *
Run Code Online (Sandbox Code Playgroud)
同样在你的反向安排中,
for filename in *; do
grep -- "$@" PathOfFileToBeSearched
done
Run Code Online (Sandbox Code Playgroud)
有一个重要的xargs警告:生成的文件名中的空白字符ls不会处理得太好.要做到这一点,只要你有GNU实用程序,你可以使用它find.
find . -mindepth 1 -maxdepth 1 -print0 | xargs -0 -n1 -J % grep -- % PathOfFileToBeSearched
Run Code Online (Sandbox Code Playgroud)
使用NUL字符分隔文件名而不是空格