awkを使用してファイルとリストの2つの列を比較し、一致しないパターンを印刷する方法

awkを使用してファイルとリストの2つの列を比較し、一致しないパターンを印刷する方法

データファイルがありますA.tsv(フィールド区切り記号= \t)。

id  mutation
243 siti,toto,mumu
254     
267 lala,siti,sojo
289 lala

とテンプレートファイルB.txt(フィールドの区切り文字=行と列が1つだけなので重要ではありません):

lala,siti,mumu

私はwasという新しい列を作成しA.tsv(しかし新しいファイルにあります)、リストにない列の突然変異のみを印刷したいと思います。C.tsvmutation_notmutationA.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

すべてのフィールドがコンマで区切られ、1行しかないと仮定すると、レコード区切り文字(RS)はファイルのコンマに設定されますB.txt

NR==FNR{ar[$1]=$1;nextar最初のファイルの最初のフィールドでインデックス付きの配列を作成します。

FNR==1{$(NF+1) = "mutation_not"ヘッダー名に列をもう1つ作成します。

FNR>1{split($2,a,",")2番目のフィールドを配列A.tsvに分割しますa

存在しない次の項目が配列に B.txt保存されます。 arrayの要素を使用して別の列を作成します。ncol$(NF+1) = ncol[$1]ncol

答え3

setB.txtファイルのカンマ区切り要素でs2を設定します。

次に、A.tsvの各行に対して2番目のフィールドをセットに変換し、ここからs2セットを減算します。これは、B.txtに見られないA.tsvに存在する突然変異を提供する。次に結果要素を連結し、元の行と一緒に印刷します。

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で見つかった突然変異を選択することです。すべての変異を確認した後、この行が印刷されます。

関連情報