Informationen aus der Datei extrahieren

Informationen aus der Datei extrahieren

Gibt es eine effiziente Möglichkeit, eine Datei wie diese zu analysieren:

2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669

Zu:

CSQ=G      ENSG00000184731         ENST00000327669    Transcript  missense_variant

Das Muster ist immer |||; - dann beginnt es mit CSQund endet mit dem fünften Feld - dieses Feld ist jedoch nicht immer, missense variantsondern kann auch etwas anderes sein, wie kdjdud.

Die Datei enthält viele Zeilen (über 60.000) und ich müsste diese Tab-Deli-Tabelle wie oben gezeigt extrahieren. Gibt es dafür eine Python-, Perl- oder AWK-Lösung (oder eine andere Lösung)?

Antwort1

Verwenden wir sed:

sed -r 's/.*\|\|\|;(CSQ[^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|.*/\1\t\2\t\3\t\4\t\5/' file.txt

pythonist nicht schnell beim Bearbeiten sehr großer Dateien, dies wäre viel schneller als python.

Beispiel:

% cat file.txt 
2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669

% sed -r 's/.*\|\|\|;(CSQ[^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|([^|]+)\|.*/\1\t\2\t\3\t\4\t\5/' file.txt
CSQ=G   ENSG00000184731 ENST00000327669 Transcript  missense_variant
CSQ=G   ENSG00000184731 ENST00000327669 Transcript  missense_variant
CSQ=G   ENSG00000184731 ENST00000327669 Transcript  missense_variant
CSQ=G   ENSG00000184731 ENST00000327669 Transcript  missense_variant

Antwort2

Mit Perl:

perl -F'\|\|\|' -lane '$, = "\t"; @f = split(/;|\|/, $F[1]); shift(@f); splice(@f, 5); print(@f)' file
  • -F'\|\|\|': setzt den Eingabefeldtrenner auf |||;
  • -l: aktiviert die automatische Zeilenendeverarbeitung. Dies hat zwei verschiedene Auswirkungen. Erstens wird $/ (der Eingabedatensatztrenner) automatisch gelöscht, wenn es mit -n oder -p verwendet wird. Zweitens wird $\ (der Ausgabedatensatztrenner) mit dem Wert octnum versehen, sodass dieser Trenner bei allen Druckanweisungen wieder hinzugefügt wird. Wenn octnum weggelassen wird, wird $\ auf den aktuellen Wert von $/ gesetzt.
  • -a: schaltet den Autosplit-Modus ein, wenn er mit -n oder -p verwendet wird. Ein impliziter Split-Befehl für das @F-Array wird als erstes innerhalb der impliziten While-Schleife ausgeführt, die durch -n oder -p erzeugt wird.
  • n: bewirkt, dass Perl die folgende Schleife um Ihr Programm annimmt, die es über Dateinamenargumente iterieren lässt, ähnlich wie sed -n oder awk:

    LINE:
      while (<>) {
          ...             # your program goes here
      }
    
  • -e: kann verwendet werden, um eine Programmzeile einzugeben.
  • $, = "\t"; @f = split(/;|\|/, $F[1]); shift(@f); splice(@f, 5); print(@f): setzt den Ausgabefeldtrenner auf \t, teilt das zweite Feld der aktuellen Zeile an ;oder |auf , entfernt das erste leere Feld und druckt die verbleibenden Felder.
% cat file
2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
% perl -F'\|\|\|' -lane '$, = "\t"; @f = split(/;|\|/, $F[1]); shift(@f); splice(@f, 5); print(@f)' file
CSQ=G   ENSG00000184731 ENST00000327669 Transcript  missense_variant
% 

Antwort3

Das sollte für Sie funktionieren:

cut -d"|" -f4,5,6,7,8 filename.txt | sed 's/;//g' | sed 's/|/\t/g'

Beispiel:

$ echo "2       41620   .       T       G       100     PASS    AC=3;AF=0.000599042;AN=5008;NS=2504;DP=18872;EAS_AF=0;AMR_AF=0;AFR_AF=0;EUR_AF=0;SAS_AF=0.0031;AA=.|||;CSQ=G|ENSG00000184731|ENST00000327669|Transcript|missense_variant|954|954|318|K/N|aaA/aaC|||-1|tolerated(0.47)|benign(0)||||;GENCODE=ENST00000327669
" | cut -d"|" -f4,5,6,7,8 | sed 's/;//g' | sed 's/|/\t/g'

CSQ=G   ENSG00000184731 ENST00000327669 Transcript  missense_variant

Erläuterung

cut -d"|" -f4,5,6,7,8 filename.txt   #-> split the line at | and return fields 4 to 8
| sed 's/;//g'                       #-> remove the ;
| sed 's/|/\t/g'                     #-> replace | with tab

Antwort4

Python-Lösung

#!/usr/bin/env python
import re,sys
with open(sys.argv[1]) as fd:
    for line in fd:
        pattern=[ x for x in re.split('\|\|\||;',line)
                    if 'CSQ' in x]
        if pattern:
            print(" ".join(pattern[0].split("|")[0:5]))

PRÜFEN

Mit der Originalzeile des OP, die dreimal neu eingefügt und leicht bearbeitet wurdeinput.txt

$ ./extract_pattern.py input.txt                                                                      
CSQ=G ENSG00000184731 ENST00000327669 Transcript missense_variant
CSQ=G ENSG00000184731 ENST00000327669 Transcript random_variant
CSQ=G ENSG00000184731 ENST00000327669 Transcript other_variant

Erläuterung

Das Skript öffnet die in der Befehlszeile als Argument angegebene Datei ( sys.argv[1]) und liest die Datei Zeile für Zeile. Wir verwenden zunächst re.split()die Funktion, um jede Zeile in mehrere Trennzeichen aufzuteilen – 3 vertikale Striche oder ;, wodurch die relevanten Daten in einem String enthalten sein können. Dann suchen wir diesen einen String (der enthält CSQ). Wenn wir ihn finden, wird der String wieder in eine Liste von Strings aufgeteilt, jetzt nur unter Verwendung .split()der Funktion mit vertikalem Strich als Trennzeichen. Die resultierende Liste wird aufgeteilt, um die ersten 5 Elemente (den [0:5]Teil) zu übernehmen, und mit Leerzeichen als Trennzeichen wieder zu einem neuen String zusammengefügt.

verwandte Informationen