0

我有一个制表符分隔的文本文件,如下所示:

文件_1:

A1  13f  Jos  +
B1  zh4  Kia  -
C2  nh2  Met  -
D3  5gh  Lox  +
F4  w4t  Nit  -

文件_2

N3  6jg  Jut -
J8  76d  Met +
A1  99g  Kia -
M6  45k  Qox +
V2  87h  Nit -

我想从 file_1 中提取条目,其中第 3 列条目与 file_2 的第 3 列条目匹配,如下所示:

    B1  zh4  Kia -   
    C2  nh2  Met -    
    F4  w4t  Nit -

comm-12 file_1.txt file_2.txt帮助吗?请指导我

4

3 回答 3

2

awk在这里可能是最简单的(这保留了file_1输入顺序):

$ awk 'NR==FNR { seen[$3]++; next } seen[$3]' file_2 file_1

B1  zh4  Kia  -
C2  nh2  Met  -
F4  w4t  Nit  -
  • PatternNR==FNR只匹配第一个输入文件 ( file_2) 中的行,并建立一个包含所有第 3 列值和 action 的关联数组{ seen[$3]++; next }

    • seen[$3]++是构造包含唯一字段值集的关联的常用习惯用法:访问$3数组中的键(第三个字段的值)会在第一次访问时为该键seen隐式创建++一个条目,后增量为该条目提供一个非零值,它在布尔上下文中评估为真(下面讨论的模式利用了这一点)。
  • 由于next前面的操作,patternseen[$3]仅对第二个输入文件 ( file_1) 执行,并且仅当第二个文件的第 3 列值也存在于第一个文件中时才计算为 true。计算结果为 true 的模式会隐式打印手头的行。

于 2016-11-12T19:52:44.330 回答
1

comm期望文件按要比较的列排序,并且其参数之前的空格不是可选的。

但是您可以使用 提取文件 1 的第三列,如果它们不能出现在任何其他列中,则可以cut从文件 2 中提取该值:grep

cut -f3 file_1 | grep -Ff- file_2

不过,这些行的顺序对应于 file2。

B1      zh4     Kia     -
C2      nh2     Met     -
F4      w4t     Nit     -

为了得到正确的顺序,我会使用 Perl:

perl -e 'until (eof) {
             @F = split " ", <>;
             $h{ $F[2] } = 1;
         }
         while (<>) {
             @F = split " ";
             print if $h{ $F[2] };
         }' file_1 file_2

它首先将 file_1 的第三列 ( $F[2]) 值存储到 hash%h中,然后遍历 file_2 并检查第 3 列的值是否设置在 hash 中。

于 2016-11-12T19:23:10.053 回答
0

awk 的答案。这对于小文件是可以的。对于大文件,看到的数组会变得很大,因为整行都$0保存在数组中。

awk 'NR==FNR { seen[$3] = $0; next} $3 in seen {print seen[$3]}' file_2 file_1

输出

A1  99g  Kia -
J8  76d  Met +
V2  87h  Nit -
于 2016-11-12T20:08:00.493 回答