Como analisar um ID específico de um arquivo de texto?

Como analisar um ID específico de um arquivo de texto?

Eu tenho um arquivo de texto longo, o conteúdo parcial do arquivo é mostrado abaixo,

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

Preciso analisar uniprotos IDs do arquivo de texto acima e o resultado esperado é fornecido abaixo,

P12807
P12807
T12807
P12808
Z12809
P12821
P0C918

Para fazer o mesmo, tentei os seguintes comandos, mas nada funciona para mim,

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

Por favor, ajude-me a analisar os IDs mencionados acima.

Desde já, obrigado.

Responder1

Se você estiver em um sistema Linux, poderá fazer facilmente:

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

Diz para imprimir apenas a parte correspondente de cada linha e habilita expressões regulares compatíveis com Perl -o. A regex está procurando, mas depois a descarta (o que significa "descartar qualquer coisa que corresponda até agora", para que não seja incluída na saída). Então, basta procurar o trecho mais longo de não- ( ).grep-P"uniprot":"\K"[^"]+


Claro, isso se parece com dados JSON, portanto, para algo mais complicado, você deve usar um analisador adequado, como jq. Se você corrigir seu arquivo adicionando um fechamento ]e deixando-o assim:

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

Você pode fazer:

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

Responder2

Se você observar com atenção, seu arquivo de entrada é uma estrutura de dados Python. Em particular, é uma lista de dicionários. Precisamos acrescentar um colchete de fechamento.

Por meio do módulo ast podemos serializar a string que é uma estrutura de dados Python válida.

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

Responder3

Usando gawk:

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

Neste comando, a entrada Record Separator( RS) é definida como vírgula.

Em seguida, gawka função integrada gensub()substitui a linha pelo padrão desejado usando backreference( \\2).

Responder4

Solução Perl 5

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

informação relacionada