¿Cómo analizar una identificación particular de un archivo de texto?

¿Cómo analizar una identificación particular de un archivo de texto?

Tengo un archivo de texto extenso; a continuación se muestra parte del contenido del archivo.

[{"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"},

Necesito analizar uniprotlos identificadores del archivo de texto anterior y el resultado esperado se proporciona a continuación:

P12807
P12807
T12807
P12808
Z12809
P12821
P0C918

Para hacer lo mismo, probé los siguientes comandos pero nada me funciona,

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

Por favor ayúdenme a analizar los identificadores como se mencionó anteriormente.

Gracias de antemano.

Respuesta1

Si estás en un sistema Linux, puedes hacer muy fácilmente:

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

Le -oindica grepque solo se imprima la parte coincidente de cada línea y -Phabilita las expresiones regulares compatibles con Perl. La expresión regular está buscando "uniprot":"pero luego la descarta (lo \Kque significa "descartar todo lo que coincida hasta ahora", para que no se incluya en la salida). Luego, simplemente busca el tramo más largo de no "( [^"]+).


Por supuesto, esto parece datos JSON, por lo que para cualquier cosa más complicada, debe usar un analizador adecuado como jq. Si arregla su archivo agregando un cierre ]y lo hace así:

[{"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"}]

Tu puedes hacer:

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

Respuesta2

Si observa con atención, su archivo de entrada es una estructura de datos de Python. En particular, es una lista de diccionarios. Necesitamos agregar un corchete de cierre.

Mediante el módulo ast podemos serializar la cadena que es una estructura de datos válida de Python.

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

Respuesta3

Usando gawk:

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

En este comando, la entrada Separador de registros ( RS) se establece en coma.

Luego, gawkla función incorporada gensub()reemplaza la línea con el patrón deseado usando referencias inversas ( \\2).

Respuesta4

solución Perl 5

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

información relacionada