我在处理基于与另一个文件的公共列的制表符分隔文件时遇到问题Column_4
。
第一个文件可能非常小(少于 100 行),但第二个文件将远远超过 80,000 个(两者都大约有 30 列)。
file1.txt
:
Column_1 Column_2 Column_3 Column_4
A1 B1 C1 D1
A2 B2 C2 D2
A3 B3 C3 D3
file2.txt
:
Column_1 Column_2 Column_3 Column_4
Aa1 Bb1 Cc1 Dd1
Aa2 Bb2 Cc2 D2
Aa3 Bb3 Cc3 Dd3
desired_output.txt
:
Column_1 Column_2 Column_3 Column_4
Aa2 Bb2 Cc2 D2
我已经尝试了一系列cut
,,grep
等等awk
,但似乎无法得到正确的结果。
最终目标是从 中删除所有不匹配的行file2.txt
,然后将输出与 进行比较file1.txt
。
答案1
如果我很好地理解你的问题,这听起来像是一个典型的问题 join(“在公共字段上连接行”)用例:
join --header -j 4 -t $'\t' file1.txt file2.txt
每个匹配行都有 7 列。
这是我得到的结果(略有修改的数据,见下文):
Column_4 Column_1 Column_2 Column_3 Column_1 Column_2 Column_3
D2 A2 B2 C2 Aa2 Bb2 Cc2
D3 A3 B3 C3 Aa3 Bb3 Cc3
D8 A8 B8 C8 Aa8 Bb8 Cc8
(抱歉,标签在这里显示得不太漂亮):
Column_4 是您的匹配值,并且排在第一位。您可以按照您的要求比较其他列的值你的目标。
如果您只需要第二个表列,请使用:
join --header -j 4 -o 2.1,2.2,2.3,2.4 -t $'\t' file1.txt file2.txt
但是,join
期望其输入文件进行排序,因此您需要传递它们sort
并首先在第四个字段上对它们进行排序:
join --header -j 4 -o 2.1,2.2,2.3,2.4 -t $'\t' <(sort -k4 file1.txt) <(sort -k 4 file2.txt)
为了更好的演示,我建议稍微不同的源文件(哼,那是在你编辑它们之前)
文件1:
Column_1 Column_2 Column_3 Column_4
A0 B0 C0 D0
A2 B2 C2 D2
A3 B3 C3 D3
A8 B8 C8 D8
文件2:
Column_1 Column_2 Column_3 Column_4
Aa1 Bb1 Cc1 D1
Aa2 Bb2 Cc2 D2
Aa3 Bb3 Cc3 D3
Aa4 Bb4 Cc4 D4
Aa5 Bb5 Cc5 D5
Aa6 Bb6 Cc6 D6
Aa7 Bb7 Cc7 D7
Aa8 Bb8 Cc8 D8
Aa9 Bb9 Cc9 D9
答案2
解决方案awk
:
$ awk -F"\t" 'FNR==NR{a[$4];next}; $4 in a' OFS="\t" file1 file2
Column_1 Column_2 Column_3 Column_4
Aa2 Bb2 Cc2 D2