使用Grep与Xargs和进程替换

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Grep与Xargs和进程替换相关的知识,希望对你有一定的参考价值。

我正在尝试通过xargs传递grep查询,同时通过进程替换传递文件。

command1 | xargs -I{} grep {} <(command2)

制作虚拟文件

for f in {1..50}; do echo $f >> test50.txt; done

for f in {25..30}; do echo $f >> test5.txt; done

使用grep进行xargs和进程替换

cat test5.txt | xargs -I{} grep {} <(cat test50.txt)

输出是:

25

期望的输出是:

25
26
27
28
29
30

我认为问题在于grep如何接收输入文件,它在一行后停止,而我希望它搜索整个输入文件

答案

使用GNU Parallel,它看起来像这样:

cat test5.txt | parallel 'grep {} <(cat test50.txt)'
另一答案

考虑一下

cat test5.txt | xargs -I{} cat {} <(cat test50.txt)

输出

cat: 25: No such file or directory
1
2
--cutted for brevity--
49
50
cat: 26: No such file or directory
cat: 27: No such file or directory
cat: 28: No such file or directory
cat: 29: No such file or directory
cat: 30: No such file or directory

这不是关于grep,而是process substitution。它创建一个命名管道,该管道中的所有数据都在第一个grep(或上面的cat)调用中使用。

这会奏效

cat test5.txt | xargs -I{} bash -c " grep {} <(cat test50.txt)"

因为它为每个grep执行独立创建进程替换。

另一答案

不需要xargs,因为grep已经有办法从文件中指定搜索词

$ seq 50 > f1
$ seq 25 30 > f2
$ grep -Fxf f2 f1
25
26
27
28
29
30

来自man grep

-F, - fixed-strings将PATTERN解释为固定字符串(而不是正则表达式)的列表,由换行符分隔,其中任何一个都要匹配。

-x, - line-regex仅选择与整行完全匹配的匹配项。对于正则表达式模式,这就像括号模式然后用^和$包围它。

-f FILE, - file = FILE从FILE获取模式,每行一个。如果多次使用此选项或与-e(--regexp)选项组合使用,请搜索给定的所有模式。空文件包含零模式,因此不匹配任何内容。

以上是关于使用Grep与Xargs和进程替换的主要内容,如果未能解决你的问题,请参考以下文章

linux--补充(管道| / 重定向> / xargs)/find 与xargs结合使用/vi,grep,sed,awk(支持正则表达式的工具程序)

linux下使用awk xargs批量杀进程

使用 grep xargs sed 更有效地在文件中生成 UUID

[linux]利用管道 + xargs批量管理文件

[linux]利用管道 + xargs批量管理文件

防止 POSIX xargs 尝试运行空命令