将列表grep到多列文件中,并获得完全匹配的行

时间:2018-09-06 13:54:07

标签: bash grep

不确定如何问这个问题,但是肯定会举例说明。假设我有这个文件:

$ cat intoThat 
a   b
a   h
a   l
a   m
b   c
b   d
b   m
c   b
c   d
c   f
c   g
c   p
d   h
d   f
d   p

和此列表:

cat grepThis 
a
b
c
d

现在我想 grepThis 变成那个,我会这样做:

$grep -wf grepThis intoThat

这将给出如下输出:

**a b**
a   h
a   l
a   m
**b c**
**b d**
b   m
**c b**
**c d**
c   f
c   g
c   p
d   h
d   f
d   p

现在,星号用于突出显示我希望grep返回的那些行。这些是具有完全匹配的行,但是...如何告诉grep(或awk等)仅获得这些行? 当然,某些行可能与任何模式都不匹配,例如在into那个文件中,我可能还有其他一些字母,例如g,h,l,s,t等...

1 个答案:

答案 0 :(得分:3)

使用awk,您可以执行以下操作:

awk 'NR==FNR{ seen[$0]++; next } ($1 in seen && $2 in seen)' grepThis intoThat
a   b
b   c
b   d
c   b
c   d
    awk 读取的第一条记录时,
  • NR设置为1,并且对于接下来读取的单个记录或多个输入文件中的每条记录,将其递增,直到读取所有记录/行。
  • FNR设置为1时, awk 读取的第一条记录将为当前文件中读取的每条下一条记录递增,如果有多个输入文件,则将下一个输入文件重新设置为1 。
  • 因此NR == FNR始终是第一个输入文件的真实条件,其后的块将仅对第一个文件执行操作。

  • seen是一个名为awk的关联seen数组(您可以根据需要使用其他名称),并用整行$0和值出现每行的情况(这种方式通常也用于删除awk中的重复记录)。

  • next令牌跳至执行其余命令,而这些命令仅对除下一个文件外的下一个文件实际执行。

  • 在下一个(....)中,我们只是检查数组中是否同时存在列$ 1和$ 2,如果存在,它们将进入输出。