如何基于一个公共列在 unix 中合并两个 .txt 文件。 Unix

How to merge two .txt file in unix based on one common column. Unix

我有两个 .txt 文件。 File1.txt 和 File2.txt。我如何根据一个公共列在 unix 中合并这两个文件(可能与 awk 一起使用)。

File1.txt 看起来像

Sub_ID  Sam_ID   v1              
1878372 2253734 SAMN06396112           
1883177 2264293 SAMN06414028          
1884646 2275341 SAMN06432785         
1860945 2277481 SAMN06407597  

File2.txt 长得像

Sam_ID  code    V3      V4 
2253734 20481   NA      DNA   
2275341 20483   NA      DNA    
2277481 20488   NA      DNA   

合并后的最终输出文件应如下所示

Finalfile.txt

Sub_ID  Sam_ID   v1               code   V3      V4
1878372 2253734 SAMN06396112     20481   NA      DNA                
1884646 2275341 SAMN06432785     20483   NA      DNA     
1860945 2277481 SAMN06407597     20488   NA      DNA  

到目前为止,我已经尝试加入,但可能是我没有完全理解该命令(刚接触 unix)。

sort -k2b File1.txt >sorted_file1.txt 
sort File2.txt >sorted_file2.txt 
join -1 2 sorted_file1.txt sorted_file2.txt > Finalfile.txt

我了解到,通过 k2b,我指定 File_1 的第二列在两者之间通用,然后合并。

感谢您添加自己的尝试来解决问题 - 它使故障排除变得容易得多。

这个答案有点令人费解,但这里有一个可能的解决方案(加入 GNU):

join -t $'\t' -1 2 -2 1 <(head -n 1 File1.txt && tail -n +2 File1.txt | sort -k2,2 ) <(head -n 1 File2.txt && tail -n +2 File2.txt | sort -k1,1)

#Sam_ID Sub_ID  v1  code    V3  V4
#2253734    1878372 SAMN06396112    20481   NA  DNA
#2275341    1884646 SAMN06432785    20483   NA  DNA
#2277481    1860945 SAMN06407597    20488   NA  DNA

解释:

  • join使用单个字符作为分隔符,所以不能使用"\t",但可以使用$'\t'(据我所知)
  • 合并文件时-1 2-2 1表示“第一个文件使用第二个字段”和“第二个文件使用第一个字段”
  • 在每个子进程 (<()) 中,按 Sam_ID 列对文件进行排序,但从排序中排除 header(根据 Is there a way to ignore header lines in a UNIX sort?

编辑

要指定列在输出中的顺序(将 Sub_ID 放在 Sam_ID 之前),您可以使用 -o 选项,例如

join -t $'\t' -1 2 -2 1 -o 1.1,1.2,1.3,2.2,2.3,2.4 <(head -n 1 File1.txt && tail -n +2 File1.txt | sort -k2,2 ) <(head -n 1 File2.txt && tail -n +2 File2.txt | sort -k1,1)

#Sub_ID Sam_ID  v1  code    V3  V4
#1878372    2253734 SAMN06396112    20481   NA  DNA
#1884646    2275341 SAMN06432785    20483   NA  DNA
#1860945    2277481 SAMN06407597    20488   NA  DNA

使用 cut greppr 以及来自 bash 的 ProcSub。

pr -mt <(grep -Fv 1883177 file1.txt) <(cut -d' ' -f2- file2.txt)

输出

Sub_ID  Sam_ID   v1                  code    V3      V4
1878372 2253734 SAMN06396112        20481   NA      DNA
1884646 2275341 SAMN06432785        20483   NA      DNA
1860945 2277481 SAMN06407597        20488   NA      DNA

paste

paste -d' ' <(grep -Fv 1883177 file1.txt) <(cut -d' ' -f2- file2.txt) | column -t > Finalfile.txt

这个awk合并任务的工作文件:

awk 'FNR==NR {map[] = [=10=]; next} {print map[], [=10=]}' File1.txt File2.txt | column -t

Sub_ID   Sam_ID   v1            Sam_ID   code   V3  V4
1878372  2253734  SAMN06396112  2253734  20481  NA  DNA
1884646  2275341  SAMN06432785  2275341  20483  NA  DNA
1860945  2277481  SAMN06407597  2277481  20488  NA  DNA

column -t 仅用于表格输出。

PS:如果在 File1 中找不到 File2 的第一列,那么您将在输出中获得前导 space。