在两个文件的列中查找具有相同值的行

时间:2017-11-23 17:57:59

标签: linux bash awk

我有两个文件(数百万列)

File1.txt ,~4k行

some_key1 some_text1
some_key2 some_text2
...
some_keyn some_textn

File2.txt ,~20 M行

some_key11 some_key11 some_text1
some_key22 some_key22 some_text2
...
some_keynn some_keynn some_textn

如果File1.txt中的第2列与File2.txt中的第3列完全匹配,我想打印出两个文件中的特定行。

修改

我试过这个(我忘记写了)但它不起作用

awk 'NR{a[$2]}==FNR{b[$3]}'$1 in a{print $1}' file1.txt file2.txt

2 个答案:

答案 0 :(得分:0)

假设您的数据集在两个维度都很大 - 行和列。然后你想使用join。要使用join,您必须先对数据进行排序。这些方面的东西:

<File1.txt sort -k2,2 > File1-sorted.txt
<File2.txt sort -k3,3 -S1G > File2-sorted.txt

join -1 2 -2 3 File1-sorted.txt File2-sorted.txt > matches.txt

sort -k2,2表示'排序整行,因此第二列的值按升序排列。 join -1 2表示'第一个文件中的键是第二列'。

如果您的文件大于100 MB,则需要通过sort选项为-S分配额外的内存。经验法则是分配输入大小的1.3倍,以避免任何磁盘交换sort。但只有你的系统可以处理它。

如果您的某个数据文件非常小(例如最多100行),您可以考虑执行类似

的操作
<File2.txt fgrep -F <( <File1.txt cut -f2 ) > File2-matches.txt

要避开sort,但是您必须从该文件中查找“密钥”。

决定使用哪一个与数据库世界中的'散列连接'和'合并连接'非常相似。

答案 1 :(得分:0)

您需要修复awk计划

如果字段3(file2)中存在字段1(file1),则打印file2中的所有记录: -

awk 'NR==FNR{A[$2];next}$3 in A' file1.txt file2.txt
some_key11 some_key11 some_text1
some_key22 some_key22 some_text2
...
some_keynn some_keynn some_textn

如果字段3(file2)中存在字段1(file1),则仅在file2中打印字段1: -

awk 'NR==FNR{A[$2];next}$3 in A{ print $1 }' file1.txt file2.txt
some_key11
some_key22
...
some_keynn