是否可以使用一个文件运行的多行输出作为对另一个文件的grep
后续第二次运行的模式?grep
例子:
- 内容
file1.txt
2 blue 1 red 1 green 2 black 2 orange
- 内容
file2.txt
2 blue triangle 2 blue circle 3 blue triangle 2 red triangle 3 green circle 4 red square 2 orange circle 2 brown circle
- 第一个结果
grep
:$ grep 2 file1.txt 2 blue 2 black 2 orange
现在,我正在寻找一个可以实现类似功能的命令
grep <PREVIOUS OUTPUT> file2.txt
这将找到其中的所有行均以运行 onfile2.txt
生成的行之一开头,因此所需的结果是:grep
file1.txt
2 blue triangle
2 blue circle
2 orange circle
答案1
这是对这个问题的回答文字问题。要获得可能更好地解决该任务的答案,请参阅awk
下面“注释”中的解决方案。
假设在 中找到的模式file1.txt
只能出现在 中 行的开头file2.txt
,您可以使用该-f
标志从文件中读取多个搜索模式,而不是在命令行上将它们声明为正则表达式。然后需要将该文件连接到第一次grep
运行的输出。
一种方法是流程替代:
grep -F -w -f <(grep -w 2 file1.txt) file2.txt
- 该
<( ... )
构造使得括号中的命令的输出可用,就像它是一个文件一样。 - 该
-F
标志禁用完整的正则表达式搜索,是为了安全起见,以防第一次grep
运行的输出可能包含在正则表达式上下文中具有特殊含义的字符。它还加快了匹配速度,因为文字字符串比较比正则表达式匹配更快。 - 该
-w
标志确保不会有部分匹配进入结果。grep
如果 的第一列file1.txt
可以包含多位数字,例如12
,这对于第一次运行尤其可取。
更新
正如 @Stéphane Chazelas 所指出的,该-f
选项接受经常(但并非总是)实现的值来-
引用程序的stdin
,因此您也可以将其写为
grep -w 2 file1.txt | grep -F -w -f - file2.txt
使用更容易识别的管道方法来读取另一个命令的输出。
笔记
这假设该模式
number color
只能作为 的前两列出现file2.txt
。如果它也可以稍后发生在线路上,如4 red square and 2 blue triangle
这样的行会被错误地识别为也匹配。
对于处理表格数据(似乎是这里的情况),
awk
通常是更适合的工具。您的任务可以通过以下程序来完成awk
:awk -v num="2" 'NR==FNR{if ($1==num){col[$2]}; next} ($1==num) && ($2 in col)' file1.txt file2.txt
这将处理这两个文件。搜索关键字通过
awk
变量指定num
。在处理第一个文件时(其中
NR
,全局行计数器,等于FNR
每个文件行计数器),它在第二列中注册颜色在数组的索引中col
col[$2]
(因此,如果第一列中的数字匹配,则没有实际分配给)。然后它会跳到下一行执行。处理第二个文件时,它检查第一列是否与变量匹配
num
,以及是否在数组的索引中找到第二列col
。如果是这样,则打印该行。
答案2
解决了:
$ grep 2 file1.txt | xargs -I{} grep {} file2.txt
2 blue triangle
2 blue circle
2 orange circle