Suchen Sie nach aufeinanderfolgenden Zeilen mit bestimmten Zeichenfolgen und ändern Sie die Datei basierend auf der Tabelle

Suchen Sie nach aufeinanderfolgenden Zeilen mit bestimmten Zeichenfolgen und ändern Sie die Datei basierend auf der Tabelle

Ich habe ein Problem mit der Textbearbeitung, das ich nicht lösen konnte. Angenommen, ich habe eine Textdatei wie die folgende (text.txt). Es wird Fälle geben, in denen auf eine Zeile mit /locus_tageine Zeile mit folgt, /geneund andere, in denen dies nicht der Fall ist. Ich möchte alle Zeilen finden, in denen /locus_tagnicht auf folgt, /geneund dann eine Tabelle (table.txt) wie die folgende verwenden, um das /locus_tagmit einem abzugleichen /geneund das /genenach seinem zu meiner Textdatei hinzuzufügen /locus_tag.

Jede Idee, wie dies zu bewerkstelligen ist, wäre großartig.

/locus_tag="LOCUS_23770"
/note="ABC"
/locus_tag="LOCUS_23780"
/note="DEF"
/locus_tag="LOCUS_23980"
/note="GHI"
/locus_tag="LOCUS_24780"
/gene="BT_4758"
/note="ONP"
/locus_tag="LOCUS_25780"
/gene="BT_4768"
/note="WZX"

Tisch

/locus_tag       /gene
LOCUS_00010      BT_4578
LOCUS_00020      BT_4577
LOCUS_00030      BT_2429

Antwort1

Mit den verlinkten Dateien funktioniert das

awk 'BEGIN{FS="[ =]+"; OFS="="}
     BEGINFILE{fno++}
     fno==1{locus["\""$1"\""]="\""$2"\""; }
     fno>1{if (old ~ /LOCUS/ && $0 !~ /gene/) print "/gene", locus[old]; old=$3; print}
    ' table file1

Vor

                     /locus_tag="LOCUS_00030"
                     /note="WP_011108293.1 hypothetical protein (Bacteroides

Nach

                     /locus_tag="LOCUS_00030"
/gene="BT_2429"
                     /note="WP_011108293.1 hypothetical protein (Bacteroides

Da Sie mit awkeiner Komplettlösung nicht vertraut sind

awk 'BEGIN{FS="[ =]+"; OFS="="}
# set up the input field separator as any group of spaces and/or =
# and set the output field separator as =

     BEGINFILE{fno++}
     # Whenever you open a file, increment the file counter fno

     fno==1{locus["\""$1"\""]="\""$2"\""; }
     # if this is the first file (i.e. table) load the array `locus[]`
     # but wrap the fields in "..." so that they are exactly like the data file entries

     fno>1{if (old ~ /LOCUS/ && $0 !~ /gene/) print "/gene", locus[old]; old=$3; print}
     # if this is a data file
     # if the current value of old (i.e. the previous line) is a LOCUS
     # and && this line ($0) isn't a gene
     # add a gene by indexing into the locus array based upon the value of old
     # because old contains the last LOCUS we found
     # in all cases
     #    set old to the 3rd field on the current line,
     #       which on any LOCUS line is the string "LOCUS_?????" and
     #    print the current line
     # See note below re $2 vs $3 and FS

    ' table file1
    # your input files, table must be first, you can have more data files if you want

Oder ohne das Multichar FS, dann behalten Sie es bei old=$2, weil es bei dem Leerzeichen vor dem Text in Ihrer Datendatei nicht umbricht, was bei dem Multichar der Fall ist.

Im Folgenden wird der Feldtrenner festgelegt, je nachdem, welche Datei Sie lesen FS=(fno==1)?" ":"=". Platz für die Tabelle und =für die Daten

awk 'BEGIN{OFS="="}
     BEGINFILE{fno++;FS=(fno==1)?" ":"="}
     fno==1{locus["\""$1"\""]="\""$2"\""; }
     fno>1{if (old ~ /LOCUS/ && $0 !~ /gene/) print "/gene", locus[old]; old=$2; print}
    ' table file1

Vorausgesetzt, die Tabellendatei ist nicht so groß, dass sie Speicher verbraucht.

Und setzen Sie einen Test ein, um eine Nachricht an fehlende Gene einzufügen, wenn es mehr passt als nur die leere/gene=

fno>1{if (old ~ /LOCUS/ && $0 !~ /gene/) print "/gene", (old in locus)?locus[old]:"\"GENE_MISSING_AT_LOCUS\""; old=$3; print}

Ändern Sie den Feldverweis für olddie Version, die FSSie verwenden

                     /locus_tag="LOCUS_00020"
/gene="GENE_MISSING_AT_LOCUS"
                     /note="WP_008765457.1 hypothetical protein (Bacteroides

Bearbeiten

Wenn man sich die Beispieldatei ansieht, auf die Sie verlinkt haben, erkennt man einfach ein Problem mit dem Formatierungsunterschied zwischen dem obigen Beispiel und Ihren tatsächlichen Daten, der die Feldnummern durcheinandergebracht hat. old=$2Musste nur geändert werden in old=$3. Oben korrigiert.

verwandte Informationen