precisa juntar apenas algumas linhas de um arquivo xml juntas [duplicado]

0

Gostaria de transformar esse XML em que apenas algumas linhas certas são unidas. Isso é para que eu possa mais tarde usar apenas linhas específicas. Se esse XML usasse atributos, os dados já estariam em uma linha. Eu não quero fazer isso com qualquer XSLT. grep, sed, awk, xmlstarlet, xpath seria ótimo

Portanto, se uma linha contiver "<instruction>" , eu preciso pegar as próximas 4 linhas e colocá-las todas em uma linha. Sem vírgulas. Como mostrado abaixo.

isso não é como a pergunta postada aqui : que tinha um padrão definido de uma data que iniciou a sequência para" participar ".

awk '
    /\<instruction\>/ && line {print line; line=""}
    {line = line ? line" "$0 : $0}
    END {print line}
'

esta dobrada na linha ATÉ a tag final, mas não trouxe a própria linha final.

A plataforma estará no servidor Windows 2012R2. Instalará os utilitários do Gnu. O arquivo tem aproximadamente 100k de tamanho.

                        <instruction>
                          <name>AAAAA</name>
                          <value>WHITE</value>
                          <type>0</type>
                        </instruction>
                        <instruction>
                          <name>BBBBB</name>
                          <value>WHITE</value>
                          <type>0</type>
                        </instruction>
                        <instruction>
                          <name>CCCCC</name>
                          <value>WHITE</value>
                          <type>0</type>
                        </instruction>
                      <routing/>
                      <phantom>False</phantom>
                      <AssemblyHistory/>

SAÍDA DESEJADA: (pode ter empacotado, mas o elemento Instrução deve estar em uma linha)

<instruction><name>AAAAA</name><value>WHITE</value><type>0</type></instruction> <instruction><name>BBBBB</name><value>WHITE</value><type>0</type></instruction> <instruction><name>CCCCC</name><value>WHITE</value><type>0</type></instruction> <routing/> <phantom>False</phantom> <AssemblyHistory/>

EXEMPLO SEMELHANTE (XML não bem formado)

data line 2
cust:
tommy
smith
123 main
endcust
data line 16
TRACE: error at xy123
cust:
mary 
smith
444 broadway
endcust
LOG: logon tty3
LOG: free memory before gc 33453211
root: ps -ealf  tty0 


data line 2
cust: tommy smith123 main endcust
data line 16
TRACE: error at xy123
cust:mary smith444 broadway endcust
LOG: logon tty3
LOG: free memory before gc 33453211
root: ps -ealf  tty0 

Copie o arquivo inteiro para stdout, sem omitir linhas. Quando você encontrar "cust:": 1) JUNTE-SE às próximas 4 linhas OU 2) JUNTE linhas até encontrar "endcust"

É a mesma coisa, mas desta vez você não pode usar uma ferramenta XML. Então, se este fosse o caso, como você resolveria isso? Se a pergunta top é XML, então tudo bem. Se não, use o segundo exemplo

    
por Jaymer Jaymer. 21.04.2018 / 06:47

4 respostas

0

Você pode usar o operador de intervalo do sed para lidar com o cenário, mas antes disso, certifique-se de que a tag e o antitag nas mesmas linhas sejam tratados. Também várias tags na mesma linha não serão tratadas.

sed -e '
    s/^[[:blank:]]*//
    \|<instruction>.*</instruction>|b
    \|<instruction>|,\|</instruction>|!b
    H;\|</instruction>|!d
    s/.*//;x;s/\n[[:blank:]]*//g;s/^\n//
' input_xml_lookalike_file
    
por 22.04.2018 / 11:04
0

Eu acho que o motivo pelo qual você quer usar o grep / sed / awk é porque você está familiarizado com eles. Isso não faz deles a ferramenta certa para o trabalho. Usando uma chave de fenda para martelar um prego só porque você sabe como usar uma chave de fenda não é uma idéia inteligente.

Você deseja ferramentas com reconhecimento de XML para isso: XSLT ou XQuery. (Para começar, o que faz você pensar que a tag <instruction> nunca conterá nenhum espaço em branco? E que o conteúdo do elemento instrução sempre será exibido em 4 linhas?)

Recebemos muitos usuários no StackOverflow perguntando como gerar XML formatado de uma maneira específica, o que restringe a escolha de ferramentas XML. Quando perguntamos por que eles precisam fazer isso, a resposta é, invariavelmente, que alguém tenha escrito um aplicativo para ler o XML usando ferramentas que não reconhecem XML, como o awk, o grep ou o Perl. Você está perdendo todo o sentido do XML (e todos os benefícios de interoperabilidade que ele traz) se você fizer isso.

    
por 21.04.2018 / 10:10
0

Para extrair, por exemplo, o valor do subnó value de cada instruction nó que também tem um subnó name cujo valor é Exterior Color usando XMLStarlet :

xmlstarlet sel -v '//instruction[name = "Exterior Color"]/value' -nl file.xml

Dado o arquivo

<?xml version="1.0"?>
<AssemblyHistory>
  <routing>
    <instruction>
      <name>Interior Finish</name>
      <value>WHITE</value>
      <type>0</type>
    </instruction>
    <instruction>
      <name>Exterior Color</name>
      <value>WHITE</value>
      <type>0</type>
    </instruction>
    <instruction>
      <name>Base Vinyl Color</name>
      <value>WHITE</value>
      <type>0</type>
    </instruction>
  </routing>
  <phantom>False</phantom>
</AssemblyHistory>

Isso retornaria a string WHITE .

O seguinte retornaria todos os name que correspondem a um valor WHITE em todos os instruction nós:

xmlstarlet sel -t -v '//instruction[value = "WHITE"]/name' -nl  file.xml
    
por 21.04.2018 / 10:21
0

isso quase funciona:

awk 'BEGIN {RS="<instruction>"; FS="\n"; OFS=""} NR>1 {$1=RS; NF--; print}'

mas pula as linhas precedentes e não para de juntar quando vê a tag / instruction

input:
LINE 0
LINE 1
LINE 2
<instruction>
<name>Glass SQFT</name>
<value>7.02</value>
<type>0</type>
</instruction>
LINE 3

output:
<instruction><name>Glass SQFT</name><value>7.02</value><type>0</type></instruction>LINE 3
    
por 21.04.2018 / 19:18