Bash produz dois resultados ao lado um do outro

1

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>
    
por user205316 22.10.2018 / 12:29

3 respostas

1
[your command] | paste -d '' - -

se juntará a linhas consecutivas.

    
por 22.10.2018 / 15:18
0

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' ).

    
por 22.10.2018 / 20:04
0

Basta enviar os dados para perl -pe 'chop if /^<reference>/'

    
por 23.10.2018 / 12:40