【问题标题】:How to merge two files into a unique file based on 2 columns of each file如何根据每个文件的 2 列将两个文件合并为一个唯一文件
【发布时间】:2019-08-21 15:36:23
【问题描述】:

我有两个制表符分隔的火,如下所示:
文件1:

cg00000292  0.780482425 chr1    10468   10470
cg00002426  0.914482257 chr3    57757816    57757817
cg00003994  0.017355388 chr1    15686237    15686238
cg00005847  0.065539061 chr1    176164345   176164346
cg00006414  0.000000456 chr7    10630   10794
cg00007981  0.018839033 chr11   94129428    94129429
cg00008493  0.982994402 chr3    10524   10524
cg00008713  0.018604172 chr18   11980954    11980955
cg00009407  0.002403351 chr3    88824577    88824578

文件2:

chr1    10468   10470   2   100 78  0.780
chr1    10483   10496   4   264 244 0.924
chr3    10524   10524   1   47  44  0.936
chr1    10541   10541   1   64  50  0.781
chr3    10562   10588   5   510 480 0.941
chr1    10608   10619   3   243 231 0.951
chr7    10630   10794   42  5292    5040    0.952
chr1    10810   10815   3   135 102 0.756

如果 file1 的第 3 列和第 4 列中的两个值都等于 file2 的第 1 列和第 2 列,并保留 file2 的所有列加上 file1 的第 2 列,我想将这两个文件合并到一个唯一文件中。
输出如下:

chr1    10468   10470   2   100 78  0.780   0.780482425  
chr3    10524   10524   1   47  44  0.936   0.982994402  
chr7    10630   10794   42  5292    5040    0.952   0.000000456  

非常感谢,
瓦希德。

我试过这个 awk 命令:

awk 'NR==FNR{a[$3,$4]=$1OFS$2;next}{$6=a[$1,$2];print}' file1.tsv file2.tsv  

但它并没有给我我正在寻找的独特输出,并且输出是两个文件的组合,如下所示:

chr1 10468 10470 2 100 cg00000292 0.780482425 0.78                                                                      
chr1 10483 10496 4 264  0.924                                                                                           
chr3 10524 10524 1 47 cg00008493 0.982994402 0.936                                                                      
chr1 10541 10541 1 64  0.781                                                                                            
chr3 10562 10588 5 510  0.941                                                                                           
chr1 10608 10619 3 243  0.951                                                                                           
chr7 10630 10794 42 5292 cg00006414 0.000000456 0.952                                                                   
chr1 10810 10815 3 135  0.756                                                                                           

【问题讨论】:

  • Minimal, complete, verifiable example 适用于此。包括实际输出,也许还包括您对它在指定点失败的原因的分析。
  • 另外,由于问题中没有提到 Python,我删除了多余的标签。
  • 我建议回滚到你的问题的this revision,并将bash标签替换为awk标签。
  • 我编辑问题。如果能重新打开就好了
  • 如果join 支持多字段连接条件,这种任务会容易得多。不过,您的 awk 走在了正确的轨道上……目前没有时间,但作为提示,in 将非常有用。

标签: bash awk


【解决方案1】:

这里的基本思想是读取第一个文件,并以每行的第三和第四列作为键,将第二列保存在一个数组中。然后对于第二个文件中的每一行,如果在第一个文件中看到它的前两列,则打印该行和第一个文件中保存的第二列。

$ awk 'BEGIN{ FS=OFS="\t" }
       NR==FNR { seen[$3,$4]=$2; next }
       ($1,$2) in seen { print $0, seen[$1,$2] }' file1.tsv file2.tsv
chr1    10468   10470   2   100 78  0.780   0.780482425
chr3    10524   10524   1   47  44  0.936   0.982994402
chr7    10630   10794   42  5292    5040    0.952   0.000000456

【讨论】:

  • 需要双键。干得好。
【解决方案2】:
# I want to merge these two files in a unique file 
# if both values in columns 3 and 4 of file1
# are equal to columns 1 and 2 of file2 
# and to keep all columns of file2 plus column 2 of file1.
join -t$'\t' -11 -21 -o2.2,2.3,2.4,2.5,2.6,2.7,2.8,1.3 <(
  <file1 awk -vFS=$'\t' -vOFS=$'\t' '{ print $3 $4,$0 }' |
  sort -t$'\t' -k1,1
) <(
  <file2 awk -vFS=$'\t' -vOFS=$'\t' '{ print $1 $2,$0 }' |
  sort -t$'\t' -k1,1
)
  1. 首先预处理文件并提取要加入的字段。
  2. 排序和加入
  3. 指定要加入的输出格式。

repl 上针对:

# recreate input files
tr -s ' ' <<EOF | tr ' ' '\t' >file1
cg00000292  0.780482425 chr1    10468   10470
cg00002426  0.914482257 chr3    57757816    57757817
cg00003994  0.017355388 chr1    15686237    15686238
cg00005847  0.065539061 chr1    176164345   176164346
cg00006414  0.000000456 chr7    10630   10794
cg00007981  0.018839033 chr11   94129428    94129429
cg00008493  0.982994402 chr3    10524   10524
cg00008713  0.018604172 chr18   11980954    11980955
cg00009407  0.002403351 chr3    88824577    88824578
EOF
tr -s ' ' <<EOF | tr ' ' '\t' >file2
chr1    10468   10470   2   100 78  0.780
chr1    10483   10496   4   264 244 0.924
chr3    10524   10524   1   47  44  0.936
chr1    10541   10541   1   64  50  0.781
chr3    10562   10588   5   510 480 0.941
chr1    10608   10619   3   243 231 0.951
chr7    10630   10794   42  5292    5040    0.952
chr1    10810   10815   3   135 102 0.756
EOF

【讨论】:

    猜你喜欢
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    相关资源
    最近更新 更多