grep 输出前一个 grep

grep 输出前一个 grep

是否可以使用一个文件运行的多行输出作为对另一个文件的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生成的行之一开头,因此所需的结果是:grepfile1.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

使用更容易识别的管道方法来读取另一个命令的输出。


笔记

  1. 这假设该模式number color只能作为 的前两列出现file2.txt。如果它也可以稍后发生在线路上,如

    4 red square and 2 blue triangle
    

    这样的行会被错误地识别为也匹配。

  2. 对于处理表格数据(似乎是这里的情况),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每个文件行计数器),它在第二列中注册颜色在数组的索引中 colcol[$2](因此,如果第一列中的数字匹配,则没有实际分配给)。然后它会跳到下一行执行。

    处理第二个文件时,它检查第一列是否与变量匹配num,以及是否在数组的索引中找到第二列col。如果是这样,则打印该行。

答案2

解决了:

$ grep 2 file1.txt | xargs -I{} grep {} file2.txt

2 blue triangle
2 blue circle
2 orange circle

相关内容