So vergleichen Sie zwei Spalten einer Datei und einer Liste und drucken nicht übereinstimmende Muster mit awk

So vergleichen Sie zwei Spalten einer Datei und einer Liste und drucken nicht übereinstimmende Muster mit awk

Ich habe eine Datendatei A.tsv(Feldtrennzeichen = \t):

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

und eine Vorlagedatei B.txt(Feldtrennzeichen = nicht wichtig, da nur eine Zeile und eine Spalte):

lala,siti,mumu

Ich möchte eine neue Spalte in A.tsv(aber in einer neuen Datei C.tsv) mit dem Namen erstellen, in der nur die in der Spalte mutation_notvorhandenen Mutationen gedruckt werden , die nicht in der Liste von vorhanden sind .mutationA.tsvB.txt

C.tsvsieht aus wie das:

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

Ich habe es mit Exclude versucht:

awk 'NR==FNR {exclude[$0];next} !($0 in exclude)' file2 file1

aber ich habe kein gutes Ergebnis. Hast du eine Idee? Danke

Antwort1

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

Antwort2

Verwendung von 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

Vorausgesetzt, alle Felder sind durch Kommas getrennt und bestehen nur aus einer Zeile, RSwird Record Separator( ) für die Datei auf Komma gesetzt B.txt.

NR==FNR{ar[$1]=$1;nextErstellt ein Array, ardas auf dem ersten Feld der ersten Datei indiziert ist.

FNR==1{$(NF+1) = "mutation_not"Erstellt eine weitere Spalte im Kopfnamen.

FNR>1{split($2,a,",")teilt das zweite Feld in A.tsvein Array auf a.

Der nächste nicht vorhandene Eintrag B.txtwird im ncolArray gespeichert. $(NF+1) = ncol[$1]Erstellt eine weitere Spalte mit Elementen des Arrays ncol.

Antwort3

Wir bilden ein sets2 aus den kommagetrennten Elementen der Datei B.txt

Dann konvertieren wir für jede Zeile von A.tsv das zweite Feld in einen Satz und subtrahieren den s2-Satz davon. Dadurch erhalten wir die in A.tsv vorhandenen Mutationen, die in B.txt nicht zu finden sind. Dann fügen wir die resultierenden Elemente zusammen und drucken sie zusammen mit der Originalzeile aus.

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

Ergebnis:

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

Dieses Mal verwenden wir den Gnu-Sed-Editor, um die Ergebnisse zu erhalten:

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

Die Idee ist, dass die Btxt-Datei in hold gespeichert wird (vorausgesetzt, sie ist eine Zeile) und jede Zeile von A.tsv mit dem Inhalt von B.txt ergänzt wird. Die in B.txt gefundenen Mutationen werden abgehakt. Nachdem alle Mutationen überprüft wurden, wird die Zeile ausgedruckt.

verwandte Informationen