mehrere Zeilen von einer Datei in eine andere kopieren

mehrere Zeilen von einer Datei in eine andere kopieren

Ich möchte grep verwenden, um alle Zeilen, die zwischen den Zeilen liegen, /protein_id=bis zum Ende der angezeigten Proteinsequenz von einer Datei in eine andere zu kopieren. Zum Beispiel aus dieser Eingabe:

 CDS             448..1269
                 /gene="nptII"
                 /note="neomycin phosphotransferase II"
                 /codon_start=1
                 /product="kanamycin resistance protein"
                 /protein_id="AAQ05967.1"
                 /db_xref="GI:33320494"
                 /translation="MAITLSATSLPISARIRAGSPAAWVERLFGYDWAQQTIGCSDAA
                 VFRLSAQGRPVLFVKTDLSGALNELQDEAARLSWLATTGVPCAAVLDVVTEAGRDWLL
                 LGEVPGQDLLSSHLAPAEKVSIMADAMRRLHTLDPATCPFDHQAKHRIERARTRMEAG
                 LVDQDDLDEEHQGLAPAELFARLKARMPDGEDLVVTHGDACLPNIMVENGRFSGFIDC
                 GRLGVADRYQDIALATRDIAEELGGEWADRFLVLYGIAAPDSQRIAFYRLLDEFF"
  regulatory      1443..2148

Ich hätte gerne diese Ausgabe:

                 /protein_id="AAQ05967.1"
                 /db_xref="GI:33320494"
                 /translation="MAITLSATSLPISARIRAGSPAAWVERLFGYDWAQQTIGCSDAA
                 VFRLSAQGRPVLFVKTDLSGALNELQDEAARLSWLATTGVPCAAVLDVVTEAGRDWLL
                 LGEVPGQDLLSSHLAPAEKVSIMADAMRRLHTLDPATCPFDHQAKHRIERARTRMEAG
                 LVDQDDLDEEHQGLAPAELFARLKARMPDGEDLVVTHGDACLPNIMVENGRFSGFIDC
                 GRLGVADRYQDIALATRDIAEELGGEWADRFLVLYGIAAPDSQRIAFYRLLDEFF"

Beachten Sie, dass die Eingabe variieren kann, indem die Zeile, die mit beginnt, regulatorydurch etwas anderes ersetzt werden kann. Unveränderlich ist, dass die Sequenz in Großbuchstaben angegeben wird und mit einem endet ". Ist dies mit grep möglich?

Antwort1

pcregrepist ein Grep-Dienstprogramm, das mit Perl 5 kompatible reguläre Ausdrücke verwendet. Reguläre Ausdrücke im Perl-Stil haben viele nützliche Funktionen, die die standardmäßigen POSIX-Ausdrücke nicht haben. Dies ist im Grunde dasselbe wie Grep, aber mit einer anderen Regexp-Syntax.

sudo apt-get install pcregrep  
pcregrep -M .*'/protein_id=.*(\n|.)*\"' path/to/input-file 

/protein_idist der Startsuchbegriff und "ist der Endsuchbegriff.

Hier ist ein verallgemeinertes Beispiel für einen Befehl zum Ausführen einer mehrzeiligen Suche nach allen Zeilen, die zwischen einem Startsuchbegriff und einem Endsuchbegriff liegen:

pcregrep -M .*'START-SEARCH-TERM.*(\n|.)*END-SEARCH-TERM' path/to/SOURCE-FILE >> path/to/DESTINATION-FILE  

Wo:

  • SOURCE-FILE ist die Datei, die Ihre Daten enthält
  • DESTINATION-FILE ist die Datei, in die die Ergebnisse kopiert werden
  • START-SEARCH-TERM ist der Startsuchbegriff
  • END-SEARCH-TERM ist der letzte Suchbegriff
  • -M, --multilineLassen Sie zu, dass Muster mit mehr als einer Zeile übereinstimmen.

Antwort2

Nein, grepkann nicht über mehrere Zeilen hinweg abgeglichen werden. Sie könnten es mit tun, pcregrepwie von @karel gezeigt, aber nicht rein grep. Da Sie wissen, dass die Proteinsequenzen immer in GROSSBUCHSTABEN geschrieben sind und mit enden ", könnten Sie stattdessen Folgendes abgleichen:

  1. sed

    sed -n '/\/protein_id=/,/^\s*[[:upper:]]\+"\s*$/{p}' two_seq.txt
    

    Das sedMuster /foo/,/bar/{p}bedeutet „drucke alle Zeilen zwischen foound aus bar“. Das -nunterdrückt die normale Ausgabe, sodass nur die angeforderten Zeilen gedruckt werden. Beachten Sie, dass das von /maskiert /protein_id=werden muss ( \/), da das /Teil des Übereinstimmungsoperators ist. Das zweite Muster ist etwas komplexer, es sucht nach 0 oder mehr Leerzeichen am Anfang der Zeile ( ^\s*), dann nach einem oder mehreren Großbuchstaben, gefolgt von einem doppelten Anführungszeichen ( [[:upper:]]") und dann nach 0 oder mehr Leerzeichen bis zum Ende der Zeile ( \s*$).

  2. Perl

    perl -ne 'print if m#/protein_id=# ... m#[A-Z]+"\s*$#' file.flat 
    

    Hier gilt das gleiche Prinzip: Der ...Bediener gibt einen Bereich an und die Linien zwischen den beiden Mustern werden gedruckt.

  3. awk

    awk '/\/protein_id=/{a=1}; a==1{print} /^\s*[[:upper:]]+"\s*$/{a=0}' file.flat 
    

    Hier setzen wir die Variable auf , awenn 1die Zeile mit dem ersten Muster übereinstimmt, und auf , 0wenn sie mit dem letzten übereinstimmt. Dann weisen wir an, awkzu drucken, wenn aes ist 1. Da „ printis“ aufgerufen wird, bevor es für das zweite Muster aauf gesetzt wird 0, wird hiermit auch die Zeile mit dem zweiten Muster eingeschlossen.

verwandte Informationen