我有一个制表符分隔的文本文件,如下所示:
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
会有帮助吗?请指导我
答案 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 -