Não use expressões regulares para analisar XML. Use uma ferramenta com reconhecimento de XML, por ex. xmllint
:
xmllint --xpath 'string(/results/testsuites/testcase/@time)' file.xml
Eu tenho esse XML:
<results><testsuites><testcase name="XXXX (XXXXX)" time="20.3817"><result>success</result></testcase><total_time value="20.3830" /></testsuites></results>
Eu quero extrair o 20.3817.
Tentando usar sed mas não está conseguindo trabalhar.
Não use expressões regulares para analisar XML. Use uma ferramenta com reconhecimento de XML, por ex. xmllint
:
xmllint --xpath 'string(/results/testsuites/testcase/@time)' file.xml
Use o lxprintf:
lxprintf -e "%s\n" total_time/@value test.xml
Com XMLStarlet :
$ xml sel -t -v '//testcase/@time' -nl data.xml
20.3817
perl
tem uma boa análise XML em XML::Twig
:
#!/usr/bin/env perl
use strict;
use warnings 'all';
use XML::Twig;
print XML::Twig -> parse ( \*DATA ) -> get_xpath('//total_time',0)->att('value');
__DATA__
<results><testsuites><testcase name="XXXX (XXXXX)" time="20.3817"><result>success</result></testcase><total_time value="20.3830" /></testsuites></results>
Ou como um forro:
perl -0777 -MXML::Twig -ne 'print XML::Twig -> parse (<>) -> get_xpath('//total_time',0)->att('value')'
Você estaria muito melhor usando uma ferramenta com reconhecimento de XML
Se realmente for um caso simples de extrair o valor do atributo time
, você pode usar sed
. Como você verá na maioria das respostas aqui, a melhor abordagem é realmente usar uma ferramenta que entende XML, mas para casos muito simples, você pode se safar com usando sed
.
xml='<results><testsuites><testcase name="XXXX (XXXXX)" time="20.3817"><result>success</result></testcase><total_time value="20.3830" /></testsuites></results>'
echo "$xml" | sed -nr 's/.* time="([0-9.]+).*//p' # GNU
28.3817
echo "$xml" | sed -n 's/.* time="\([0-9.]*\).*//p' # Non-GNU
28.3817
ou grep
echo "$xml" | grep -Po '(?<=time=")([0-9.]+)' # GNU
20.3817
Mas eu ainda prefiro algo com reconhecimento de XML como xmlstarlet
, que pode reconhecer time
como um atributo de <testcase>
.