我有一个数据文件A.tsv
(字段分隔符= \t
):
id mutation
243 siti,toto,mumu
254
267 lala,siti,sojo
289 lala
和一个模板文件B.txt
(字段分隔符=不重要,因为只有一行和一列):
lala,siti,mumu
我想在A.tsv
(但在新文件中C.tsv
)创建一个名为mutation_not
were 的新列,仅打印列表中不存在的列中mutation
存在的突变。A.tsv
B.txt
C.tsv
看起来像这样:
id mutation mutation_not
243 siti,toto,mumu toto
254
267 lala,siti,sojo sojo
289 lala
我尝试排除:
awk 'NR==FNR {exclude[$0];next} !($0 in exclude)' file2 file1
但我没有任何好的结果。你有好主意吗?谢谢
答案1
awk ' BEGIN{OFS="\t"}
NR==FNR{ for(i=1; i<=NF; i++) muts[$i]; next }
FNR>1 { len=split($2, tmp, ",");
for(i=1; i<=len; i++) buf= buf (tmp[i] in muts?"":(buf==""?"":",") tmp[i])
}
{ print $0, (FNR==1?"mutation_not":buf); buf="" }' FS=',' fileB FS='\t' fileA
答案2
使用gawk
:
awk 'BEGIN{OFS="\t"; }
NR==FNR{ar[$1]=$1;next}
FNR==1{$(NF+1) = "mutation_not"}
FNR>1{split($2,a,",");
for(i in a) if (a[i] in ar) ;
else ncol[$1] = (ncol[$1])? ncol[$1] "," a[i] : a[i];
$(NF+1) = ncol[$1]}1'
RS="," B.txt RS="\n" FS="\t" A.tsv
假设所有字段都用逗号分隔并且只有一行,则 Record Separator( RS
) 对于 file 被设置为逗号B.txt
。
NR==FNR{ar[$1]=$1;next
ar
创建一个以第一个文件的第一个字段为索引的数组。
FNR==1{$(NF+1) = "mutation_not"
在标题名称中再创建一列。
FNR>1{split($2,a,",")
将 的第二个字段拆分A.tsv
为数组a
。
下一个不存在的条目B.txt
将保存到ncol
数组中。
$(NF+1) = ncol[$1]
使用 array 的元素再创建一列ncol
。
答案3
我们将由set
文件 B.txt 的逗号分隔元素组成 s2
然后,对于 A.tsv 的每一行,我们将第二个字段转换为一个集合,并从中减去 s2 集合。这让我们得到了 A.tsv 中存在的突变,而 B.txt 中没有发现这些突变。然后我们连接结果元素并将其与原始行一起打印。
python3 -c 'import sys
tsv,txt = sys.argv[1:]
fs,rs = "\t","\n"
ofs,dlm = fs,","
with open(txt) as fh, open(tsv) as f:
s2 = set(*list(map(lambda x:x.rstrip(rs).split(dlm),fh.readlines())))
for nr,ln in enumerate(f,1):
l = ln.rstrip(rs)
if nr == 1: print(l,"mutation_not",sep=ofs)
else:
F = l.split(ofs)
if len(F) < 2: print(l)
else: print(l,
dlm.join({*F[1].split(dlm)}-s2),sep=ofs)
' A.tsv B.txt
结果:
id mutation mutation_not
243 siti,toto,mumu toto
254
267 lala,siti,sojo sojo
289 lala
这次我们将使用Gnu sed编辑器来获取结果:
sed -Ee '
1{h;d;}
2s/\tmutation$/&&_not/;t
s/\t\S+$/&&,/;T;G
s/\t/\n/2;ta
:a
s/\n([^,]+),(.*\n(.*,)?\1(,|$))/\n\2/;ta
s/\n([^,\n]+),/\t\1\n/;ta
s/\n.*//
' B.txt A.tsv
想法是,Btxt 文件存储在保留中(假设它是一行),A.tsv 的每一行都附加 B.txt 内容,并勾选 B.txt 中找到的突变。查看完所有突变后,将打印该行。