如果其他字段匹配则连接列

如果其他字段匹配则连接列

我有一个包含 6 个字段的制表符分隔文件。如果 fields $1$2$4$5$6匹配,我想将它们合并到一行中,并将字段$3/每个值之间的连接起来。

输入.txt

1   109860777   COSN18724706    CT  C   SORT1
1   154842199   COSM3685920 G   GGCTGCTGCTGCTGCT,GGCTGCTGCTGCTGCTGCT    KCNN3
1   154842199   COSM5827506 G   GGCTGCTGCTGCTGCT,GGCTGCTGCTGCTGCTGCT    KCNN3
1   1684347 COSM1320773 C   CCCT    NADK
1   1684347 COSM1320774 C   CCCT    NADK
1   1684347 COSM5827581 C   CCCT    NADK
1   248801602   COSM246232  T   TCA OR2T35

输出.txt

1   109860777   COSN18724706    CT  C   SORT1
1   154842199   COSM3685920/COSM5827506 G   GGCTGCTGCTGCTGCT,GGCTGCTGCTGCTGCTGCT    KCNN3
1   1684347 COSM1320773/COSM1320774/COSM5827581 C   CCCT    NADK
1   248801602   COSM246232  T   TCA OR2T35

我尝试过使用 awk,但我可以在正确的方向上使用推送。

答案1

awk解决方案:

awk '{ k=$1 FS $2 FS $4 FS $5 FS $6;  a[k]=(k in a)? a[k]"/"$3 : $3 }
     END{ for(i in a) { 
              split(i,b,FS); b[3]=a[i]"\t"b[3]; r=""; 
              for(j=1;j<=NF;j++) { 
                  r=(r!="")? r"\t"b[j] : b[j] 
              } 
              print r 
        } 
     }' input

输出:

1   1684347 COSM1320773/COSM1320774/COSM5827581 C   CCCT    NADK    
1   109860777   COSN18724706    CT  C   SORT1   
1   154842199   COSM3685920/COSM5827506 G   GGCTGCTGCTGCTGCT,GGCTGCTGCTGCTGCTGCT    KCNN3   
1   248801602   COSM246232  T   TCA OR2T35

细节

  • k=$1 FS $2 FS $4 FS $5 FS $6- 复杂的数组键

  • a[k]=(k in a)? a[k]"/"$3 : $3- 将记录的第三个字段值与匹配/分组字段连接起来

  • split(i,b,FS)- 通过分隔符分割数组键

  • b[3]=a[i]"\t"b[3]- 将结果(第三个字段)值插入相应位置

答案2

为了GNU sed便于代码外观,我们可以按如下方式执行:

sed -Ee '
   $!N
   s|^(\S+\t\S+\t)(\S+)(\t\S+\t\S+\t\S+)(\n)\1(\S+)\3$|\4\1\2/\5\3|
   /^\n/!P;D
' yourfile

结果

1       109860777       COSN18724706    CT      C       SORT1
1       154842199       COSM3685920/COSM5827506 G       GGCTGCTGCTGCTGCT,GGCTGCTGCTGCTGCTGCT    KCNN3
1       1684347 COSM1320773/COSM1320774/COSM5827581     C       CCCT    NADK
1       248801602       COSM246232      T       TCA     OR2T35

在职的

  • GNU sed使用启用-E扩展 RE 的选项进行调用。
  • 加载模式中的下一行,除非它是 eof。
  • 我们假设字段之间没有前导/尾随 TAB,也没有多个 TAB。
  • 将 $1 $2 放入 \1,将 $3 放入 \2,将 $4、$5、$6 放入 \3。
  • 然后尝试制作如图所示的子组件。如果成功,那么我们会将下一行的 $3 移动到当前行的 $3 中,并在 BOL 处用斜杠和换行符分隔。
  • 然后我们在子程序失败时打印当前行,OTW,我们用模式空间中的内容重做 sed 代码。

答案3

这是使用 Python 实现此目的的一种方法:

代码:

from collections import OrderedDict
data = OrderedDict()
with open('file1', 'rU') as f:
    for line in f.readlines():
        line = line.split('\t')
        key = tuple(line[:2] + line[3:])
        data.setdefault(key, []).append(line[2])

with open('file2', 'w') as f:
    for k, v in data.items():
        f.write('\t'.join([k[0], k[1], '/'.join(v)] + list(k[2:])))

结果:

1   109860777   COSN18724706    CT  C   SORT1
1   154842199   COSM3685920/COSM5827506 G   GGCTGCTGCTGCTGCT,GGCTGCTGCTGCTGCTGCT    KCNN3
1   1684347 COSM1320773/COSM1320774/COSM5827581 C   CCCT    NADK
1   248801602   COSM246232  T   TCA OR2T35

相关内容