我有三个非常大的文件,我只想获取文件1的前20个ID2的匹配ID2(在本例中,我只列出了5个(。我希望它完整地搜索文件2和文件3,并从文件1中取出与20个ID2匹配的行。我还想要ID1——即使它是空的(以及在同一匹配ID2行上的其他列(。
我知道如何在python中做到这一点,但由于文件太大,我的计算机无法处理它。我一直在尝试在终端(unix(中做这件事,但没有成功。我尝试了以下命令,但1(它不处理三个文件,2(它也给我带来了一个错误(也许我抓错了列(?
awk ‘NR==FNR{a[$1][$0];next} $0 in a {for (i in a[$0]) print i}’ file1.tsv file2.tsv
错误:
zsh: parse error near `}'
另一个问题:在执行命令时,如何跳过unix中的前五行(因为这些文件的开头有一些注释,这些注释是作为行读取的(?
file1
id 1 id2 name
A00000004 B00000004 emily
B00000005 joe
A00000006 B00000006 jack
B00000007 john
A00000008 B00000008 sally
file2
id1 id2 source source_code
A00000001 B00000001 source1 321
A00000003 B00000003 source2 165
A00000004 B00000004 source3 481
A00000005 B00000005 source2 891
file 3
id2 code
B00000006 yes
B00000007 no
B00000005 yes
B00000004 yes
B00000012 yes
Desired:
id1 id2 name source source_code code
A00000004 B00000004 emily source3 481 yes
A00000005 B00000005 joe source2 891 yes
首先,从文件的第N行开始:
tail -n +N infile
要匹配不同文件中的id2
列,我建议使用join
命令。然而,也有一些缺点,包括需要知道哪些列包含id2
,以及需要对这些列进行排序。此方法也不会识别多个相同的列(例如,id1
列将对其出现的每个文件重复(。从这个问题中我也不清楚是否有你想保留的标题。此方法将丢失标头。
# Sort files on the id2 column
# First, drop the header line.
# Then sort on the common column (in this case the 2nd field).
# "-t $'t'" means to use tabs as the field separator.
tail -n +2 file1 | sort -t $'t' -k2,2 > file1.sort
tail -n +2 file2 | sort -t $'t' -k2,2 > file2.sort
tail -n +2 file3 | sort -t $'t' -k1,1 > file3.sort
首先加入file1.sort
到file2.sort
:
# The "-j 2" flag means that both files use the second column as the common field.
# One could also use "-1 2 -2 2" to specify the field for the first and second files.
join -t $'t' -j 2 file1.sort file2.sort > file1-2
然后将该文件连接到file3.sort
。请注意,默认情况下,join
的输出会将联接列放在第一位。
join -t $'t' -j 1 file1-2 file3.sort > files1-3
您可以通过组合最后两个命令来保存一个步骤和一个中间文件:
join -t $'t' -j 2 file1.sort file2.sort | join -t $'t' -j 1 - file3.sort > files1-3
>cat files1-3
B00000004 A00000004 emily A00000004 source3 481 yes
B00000005 joe A00000005 source2 891 yes
如果你知道列是按照示例中的方式排列的,你也可以使用join
的输出格式来稍微清理一下:
join -t $'t' -j 2 file1.sort file2.sort | join -t $'t' -j 1 -o 1.4,1.1,1.3,1.5,1.6,2.2 - file3.sort > files1-3_format
>cat files1-3_format
A00000004 B00000004 emily source3 481 yes
A00000005 B00000005 joe source2 891 yes