我有两个文件,如下所示,以制表符分隔:
档案A
chr1 123 aa b c d
chr1 234 a b c d
chr1 345 aa b c d
chr1 456 a b c d
....
档案B
chr1 123 aa c d e ff
chr1 345 aa e f g gg
chr1 123 aa c d e hh
chr1 567 aa z c a ii
chr1 345 bb x q r kk
chr1 789 df f g s ff
chr1 345 sh d t g ll
...
我想基于2个键列“chr1”,“123”从文件B向文件A添加新列,即(前两列是键列)。如果两个文件中的键列匹配,则应将文件B中第7列中的数据添加到文件A中的第3列。
例如(chr1 123)键在文件B中找到两次,因此文件A中的第3列有ff,hh用逗号分隔。如果找不到密钥,则应该输入NA,输出应如下所示: 输出:
chr1 123 ff,hh aa b c d
chr1 234 NA a b c d
chr1 345 gg,kk,ll aa b c d
chr1 456 NA a b c d
我使用awk解决方案实现了这个目标
awk -F'\t' -v OFS='\t' 'NR==FNR{a[$1FS$2]=a[$1FS$2]?a[$1FS$2]","$7:$7;next}{$3=(($1FS$2 in a)?a[$1FS$2]:"NA")FS $3}1' fileB fileA
现在,我想添加另一列6和第7列。有人可以建议如何做到这一点吗? 输出如下:
chr1 123 ff,hh e,e aa b c d
chr1 234 NA NA a b c d
chr1 345 gg,kk,ll g,r,g aa b c d
chr1 456 NA NA a b c d
由于
答案 0 :(得分:0)
我的建议是使用另一个数组来跟踪你想要添加的下一个变量,但是为了使代码更具可读性,我制作了一个可执行的awk脚本来概括它:
#!/usr/bin/awk -f
BEGIN { FS="\t"; OFS="\t" }
{ key = $1 FS $2 }
FNR==NR {
updateArray( a, $7 )
updateArray( b, $6 )
next
}
{ $3 = concat( a, concat( b, $3 ) ) }
1
function updateArray( arr, fld ) {
arr[key] = arr[key]!="" ? arr[key] "," fld : fld
}
function concat( arr, suffix ) {
return( (arr[key]=="" ? "NA" : arr[key]) OFS suffix )
}
以下是细分:
FS
和OFS
值key
a
和b
中,并通过引用函数updateArray
传递它们,并通过值传递字段值$3
函数concat
1
作为另一种选择,您可以将存储在单个a[key]
中的值等于您希望在file B
中表示的所有$3
字段,并将它们分隔为OFS
。这需要在解析a[key]
时每次更改file B
时解析和重新组合值,但会使$3
创建一个简单的三部分连接。