如何使用 awk 比較文件和列表的兩列並列印不匹配的模式

如何使用 awk 比較文件和列表的兩列並列印不匹配的模式

我有一個資料檔案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_notwere 的新列,僅列印清單中不存在的列中mutation存在的突變。A.tsvB.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;nextar建立一個以第一個檔案的第一個欄位為索引的陣列。

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 中找到的突變。查看完所有突變後,將列印該行。

相關內容