Wie analysiere ich eine bestimmte ID aus einer Textdatei?

Wie analysiere ich eine bestimmte ID aus einer Textdatei?

Ich habe eine lange Textdatei, deren Inhalt teilweise unten angezeigt wird.

[{"site":"1a2v_1","pfam":"Cu_amine_oxid","uniprot":"P12807"},{"site":"1a2v_2","pfam":"Cu_amine_oxid","uniprot":"P12807"},{"site":"1a2v_3","pfam":"Cu_amine_oxid","uniprot":"T12807"},{"site":"1a2v_4","pfam":"Cu_amine_oxid","uniprot":"P12808"},{"site":"1a2v_5","pfam":"Cu_amine_oxid","uniprot":"Z12809"},{"site":"1a2v_6","pfam":"Cu_amine_oxid","uniprot":"P12821"},{"site":"1a3z_1","pfam":"Copper-bind,SoxE","uniprot":"P0C918"},

Ich muss uniprotIDs aus der obigen Textdatei analysieren und das erwartete Ergebnis ist unten angegeben:

P12807
P12807
T12807
P12808
Z12809
P12821
P0C918

Um dasselbe zu tun, habe ich die folgenden Befehle ausprobiert, aber nichts funktioniert bei mir,

sed -e 's/"uniprot":"\(.*\)"},{"site":"/\1/' file.txt
cat file.txt | sed 's/.*"uniprot":" //' | sed 's/"site":".*$//'

Helfen Sie mir bitte, die IDs wie oben erwähnt zu analysieren.

Dank im Voraus.

Antwort1

Wenn Sie ein Linux-System verwenden, können Sie Folgendes ganz einfach tun:

$ grep -oP '"uniprot":"\K[^"]+' file
P12807
P12807
T12807
P12808
Z12809
P12821
P0C918

Das -ogibt an grep, nur den übereinstimmenden Teil jeder Zeile zu drucken, und das -Paktiviert Perl-kompatible reguläre Ausdrücke. Der reguläre Ausdruck sucht danach, "uniprot":"verwirft ihn dann aber (das \Kbedeutet „alles bisher Übereinstimmungsvolle verwerfen“, sodass es nicht in die Ausgabe aufgenommen wird). Dann suchen Sie einfach nach dem längsten Abschnitt ohne "( [^"]+).


Natürlich sieht das wie JSON-Daten aus, also sollten Sie für alles, was komplizierter ist, einen geeigneten Parser wie verwenden jq. Wenn Sie Ihre Datei reparieren, indem Sie einen Abschluss hinzufügen ], machen Sie es so:

[{"site":"1a2v_1","pfam":"Cu_amine_oxid","uniprot":"P12807"},{"site":"1a2v_2","pfam":"Cu_amine_oxid","uniprot":"P12807"},{"site":"1a2v_3","pfam":"Cu_amine_oxid","uniprot":"T12807"},{"site":"1a2v_4","pfam":"Cu_amine_oxid","uniprot":"P12808"},{"site":"1a2v_5","pfam":"Cu_amine_oxid","uniprot":"Z12809"},{"site":"1a2v_6","pfam":"Cu_amine_oxid","uniprot":"P12821"},{"site":"1a3z_1","pfam":"Copper-bind,SoxE","uniprot":"P0C918"}]

Du kannst tun:

$ jq -r '.[].uniprot' file
P12807
P12807
T12807
P12808
Z12809
P12821
P0C918

Antwort2

Wenn Sie genau hinschauen, ist Ihre Eingabedatei eine Python-Datenstruktur. Genauer gesagt handelt es sich um eine Liste von Wörterbüchern. Wir müssen eine schließende eckige Klammer anhängen.

Mithilfe des ast-Moduls können wir den String serialisieren, der eine gültige Python-Datenstruktur ist.

python3 -c 'import sys, ast
ifile,key = sys.argv[1:]
str = ""
with open(ifile) as fh:
  for l in fh: str += l.rstrip()
  lod = ast.literal_eval(str)
  for d in lod: print(d[key])
' file uniprot

P12807
P12807
T12807
P12808
Z12809
P12821
P0C918

Antwort3

Verwendung von gawk:

awk 'BEGIN{RS=","}
/uniprot/{print gensub(/.*("uniprot":")(.*)".*/, "\\2", "g") }' input

In diesem Befehl wird der eingegebene Datensatztrenner ( RS) auf Komma gesetzt.

Dann ersetzt gawkdie integrierte Funktion gensub()die Zeile mithilfe von Backreferencing( \\2) durch das gewünschte Muster.

Antwort4

Perl 5-Lösung

$ perl -nle 'print join"\n",m/uniprot\":\"(.*?)\"/g' file.txt
P12807
P12807
T12807
P12808
Z12809
P12821
P0C918
$

verwandte Informationen