根据另一个file_2从file_1中获取行

时间:2016-11-12 19:13:03

标签: linux awk file-comparison

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

file_1:

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

file_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会有帮助吗?请指导我

3 个答案:

答案 0 :(得分: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  -
  • 模式NR==FNR仅匹配第一个输入文件(file_2)中的行,并使用操作{ seen[$3]++; next }构建所有第3列值的关联数组

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

答案 1 :(得分:1)

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

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

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])值存储到散列%h中,然后它遍历file_2并检查是否在散列中设置了第3列的值。

答案 2 :(得分: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 -