SED substitui em várias linhas

7

Estou tentando encontrar essas três linhas:

<!--
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
-->

e substitua-os por:

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

Quando eu tento

sudo sed -i 's:<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->:<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />:' /myfile.xml

Ele não o encontrou, eu também tentei colocar \ n nele, mas ele ainda não funcionou:

sudo sed -i 's:<!--\n <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />\n -->:<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />:' /myfile.xml

Estes não apresentam erros, mas não descomentam a linha. Qualquer conselho ajudaria, obrigado!

    
por Doug Molineux 20.05.2011 / 21:14

4 respostas

4

sed lê cada linha, por isso nunca irá corresponder a um padrão de múltiplas linhas, a menos que você o leve na direção certa. O comando N lê uma linha da entrada e a anexa ao espaço padrão.

sed -i -e '/^<!--$/ {
    N; /\n<Connector port="8009" protocol="AJP\/1\.3" redirectPort="8443" \/>$/ {
        N; /\n-->$/ {
            s/^<!--\n//; s/\n-->$//
        }
    }
}' /myfile.xml
Provavelmente, se você precisar de um comando diferente de s , então você deve mudar de sed para awk ou perl. Aqui está um trecho de Perl ligeiramente mais flexível que lida com comentários multilinhas de uma forma mais geral.

perl -i -pe '
    if (/<!--/) { $_ .= <> while !/-->/;
        s[<!--\n(<Connector port="8009" protocol="AJP/1\.3" redirectPort="8443" />)\n-->][$1];
    }' /myfile.xml
    
por 20.05.2011 / 21:47
5

Sed trabalha linha por linha. Pode ser feito para trabalhar em várias linhas, mas não foi projetado dessa maneira - e na minha opinião isso definitivamente mostra quando você tenta usar assim. Mas se você decidir ir por esse caminho, você provavelmente terá que usar registros. Verifique algumas das soluções para link para ver como ele pode ser feito.

Eu prefiro usar perl ao invés de sed para esse tipo de tarefa (multi-line-oriented, quero dizer). O clichê que você precisa adicionar antes da pesquisa e substituição ( BEGIN... ) não é óbvio, mas o regex parece mais limpo para mim:

perl -i.bak -pe 'BEGIN{undef $/;} s/<!--string-->/string/smg' file.xml

Ou, usando o agrupamento para encurtar a expressão e permitir que você use um regex lá:

perl -i.bak -pe 'BEGIN{undef $/;} s/<!--(string_or_regex)-->//smg' file.xml

Ele deve funcionar tanto em ocorrências com e sem novas linhas entre os marcadores de comentário e o código a ser descomentado.

Adaptado de:

link

    
por 20.05.2011 / 21:19
2

Aqui está uma descrição dos comandos de múltiplas linhas no SED: link

É uma dor na bunda. Você pode seguir o conselho de Eduardo e usar perl -i -p -e .

    
por 20.05.2011 / 21:43
1
  • /<\!--/ : string correspondente
  • :X : este é um rótulo para o comando de ramificação "b"
  • /-->/ : string correspondente
  • s@...@...@p : tira "<! -", "- >" e imprima o resultado
  • d : apaga o espaço padrão e inicia um novo ciclo
  • N : se não combinar com / - > /, em seguida, anexe uma linha
  • bX : ramificação para: X label
  • p : apenas imprima uma string que não corresponda a / <! - /

sed -rn '
/<!--/ {
    :X
    /-->/ {
        s@<!--\s*(<.+/>)\s*-->@@p
        d
    }
    N
    bX
};p'
    
por 14.01.2017 / 22:30

Tags