[your command] | paste -d '' - -
se juntará a linhas consecutivas.
Eu tenho um fora do xmllint e egrep que gostaria de imprimir dois campos ao lado do outro. por exemplo,
(xmlinput) xmllint --format | egrep reference\|sourcefile
<reference>ItemX</reference>
<sourcefile>://filepath/blah/blah/</sourcefile>
<reference>ItemY</reference>
<sourcefile>://filepath/blah/blah/</sourcefile>
.
.
<reference>ItemW</reference>
<sourcefile>://filepath/blah/blah/</sourcefile>
Existe uma maneira de gerar a referência e os elementos sourcefile um ao lado do outro? por exemplo,
(xmlinput) xmllint --format | egrep reference\|sourcefile
<reference>ItemX</reference><sourcefile>://filepath/blah/blah/</sourcefile>
<reference>ItemY</reference><sourcefile>://filepath/blah/blah/</sourcefile>
.
.
<reference>ItemW</reference><sourcefile>://filepath/blah/blah/</sourcefile>
Uma vez que você começa a usar grep
no XML, você está fazendo suposições sobre a entrada, e você (quase certamente) não terá mais saída XML válida, então, às vezes, esse não é o melhor caminho a seguir.
Dito isso, o caminho de menor resistência geralmente envolve grep
, portanto, dependendo do seu XML (um exemplo mínimo bem formado seria útil), você deve ser capaz de usar xmllint
com --xpath
( xmllint
> = 2.7.7 para --xpath
support) desta forma:
xmllint --xpath "//reference|//sourcefile" input.xml |
pcregrep -o "(<reference>.*?</sourcefile>)"
em que xmllint
extrai elementos usando uma expressão XPath que corresponde a ( |
como lógico "ou") dos elementos de seu interesse ( //
para selecionar todos os elementos correspondentes em qualquer lugar da entrada). O (não ciente de XML) pcregrep
(em vez de egrep
) corresponde a cada par de elementos com o agrupamento e gera uma saída por grupo para cada grupo correspondente.
Um ponto a ser observado aqui é a regex .*?
, que é uma correspondência não-vorazes para que corresponda à quantidade mínima de texto entre as tags indicadas, em vez da linha inteira de uma só vez ( xmllint --xpath ...
vai despejar tudo em uma linha).
É "trapacear" um pouco para usar o grep, estamos fazendo suposições sobre a entrada, mas xmllint
está fazendo a maior parte do trabalho pesado. Essa abordagem pode causar problemas de análise no futuro, já que XML isn "regular" e expressões regulares não são a melhor ferramenta para o trabalho.
A melhor maneira de fazer isso é com o XMLStarlet :
xml select -t -m '//*' \
--if 'local-name()="reference"' -c . \
--elif 'local-name()="sourcefile"' -c . -o $'\n' input.xml
Isso pesquisa todos os elementos ( //*
), na correspondência <reference>
desse nó é copiado para a saída ( -c .
), senão na correspondência <sourcefile>
desse nó é copiado para saída com uma saída extra nova ( -o $'\n'
).
Basta enviar os dados para perl -pe 'chop if /^<reference>/'
Tags grep output xml text-formatting