在unix中基于三个.tsv文件创建一个新文件



我有三个非常大的文件,我只想获取文件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.sortfile2.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

最新更新