Inserir várias linhas após a partida usando o comando sed do Mac

1

Eu tenho 2 arquivos: -

a.xml

<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        ...
    </parent>
</project>

b.xml

<project>
    <modelVersion>4.0.0</modelVersion>
</project>

Eu quero copiar <parent>...</parent> de a.xml e colocá-lo após </modelVersion> em b.xml: -

Isto é o que eu tenho: -

PARENT='awk '/<parent>/,/<\/parent>/' a.xml | tr '\n' ' ''
sed -i '' "s|</modelVersion>|</modelVersion> ${PARENT}|g" "b.xml"

Enquanto ele funciona, ele parece não formatado porque eu preciso substituir a quebra de linha por espaço para evitar que sed reclama de quebras de linha sem escape.

<project>
  <modelVersion>4.0.0</modelVersion>     <parent>         ...     </parent> 
</project> 

Como faço para que o b.xml seja assim?

<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        ...
    </parent>
</project>

Estou usando o Mac, a propósito.

    
por limc 25.07.2015 / 00:52

2 respostas

0

Isso deve funcionar. Eu sinto alguns problemas em somente afetar a primeira ocorrência de <parent>...</parent> e </modelVersion> *$ - senão poderia ser mais simples. Ele também escapa de todos os caracteres a ppended corretamente apenas no caso.

sed -e'/^ *<parent>/!d;:n'      \
    -e'$d;N;/\n *<.parent>/!bn' \
    -e's/[\[:space:]]/\&/g'    \
    -e's|.*\(.\n\)|/<.modelVersion> *$/a&|;q' a.xml |
sed -e'1,/<\/modelVersion> *$/{' -f- -e\}       b.xml

Não tenho 100% de certeza de que o BSD sed reconhecerá - para significar stdin. Se bem me lembro, faz , mas, apenas no caso, você pode substituir o -f- pelo switch e o argumento -f/dev/fd/0 se você precisar.

Aqui está o script que o primeiro sed grava no segundo stdin de sed :

/<.modelVersion> *$/a\
\ \ \ \ <parent>\
\ \ \ \ \ \ \ \ ...\
\ \ \ \ </parent>

E quando o segundo sed coincide com o primeiro </modelVersion> *$ na entrada, ele anexa a sequência para se parecer com:

<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        ...
    </parent>
</project>
    
por 25.07.2015 / 01:30
0

Experimente com awk

awk '/parent/,/\/parent/{s=s"\n"$0}/\/modelVersion/{$0=$0s}NR!=FNR' a.xml b.xml

ou sed com arquivo temporário

sed -n '/parent/,/\/parent/w part
        1!{
            /^.project/,${
                /\/modelVersion/r part
                p
                          }
           }' a.xml b.xml

ou com espaço de espera

sed -n '/parent/,/\/parent/H
        1!{
           /^.project/,${
               /\/modelVersion/{
                   G
                   s/\n//
                       }
               p
                         }
           }' a.xml b.xml
    
por 25.07.2015 / 13:30

Tags