我有一个包含 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