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 uniprot
os 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, gawk
a 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
$