Remplacement SED sur plusieurs lignes


11

J'essaie de trouver ces trois lignes:

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

et remplacez-les par:

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

Quand j'essaye

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

Il ne le trouve pas, j'ai également essayé de le mettre \ n, mais cela n'a toujours pas fonctionné:

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

Ceux-ci ne génèrent aucune erreur, mais ne décommentent pas la ligne. Tout conseil serait utile merci!

Réponses:


6

sed lit chaque ligne tour à tour, donc elle ne correspondra jamais à un modèle multiligne à moins que vous ne la poussiez dans la bonne direction. La Ncommande lit une ligne de l'entrée et l'ajoute à l'espace de motif.

sed -i -e '/^<!--$/ {
    N; /\n<Connector port="8009" protocol="AJP\/1\.3" redirectPort="8443" \/>$/ {
        N; /\n-->$/ {
            s/^<!--\n//; s/\n-->$//
        }
    }
}' /myfile.xml

Sans doute, si vous avez besoin d'une commande autre que s, alors vous devriez passer de sed à awk ou perl. Voici un extrait de Perl légèrement plus flexible qui gère les commentaires multilignes de manière plus générale.

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

6

Sed fonctionne ligne par ligne. Il peut être fait pour fonctionner sur plusieurs lignes, mais il n'a pas été conçu de cette façon - et à mon avis, il apparaît clairement lorsque vous essayez d'utiliser comme ça. Mais si vous décidez de suivre cette voie, vous devrez probablement utiliser des registres. Consultez certaines des solutions de /programming/1251999/sed-how-can-i-replace-a-newline-n pour voir comment cela peut être fait.

Je préfère utiliser perl au lieu de sed pour ce genre de tâche (orientée sur plusieurs lignes, je veux dire). Le passe-partout que vous devez ajouter avant la recherche et le remplacement ( BEGIN...) n'est pas évident, mais l'expression régulière me semble plus propre:

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

Ou, en utilisant le regroupement pour raccourcir l'expression et pour vous permettre d'y utiliser une expression régulière:

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

Il devrait fonctionner à la fois sur les occurrences avec et sans sauts de ligne entre les marqueurs de commentaire et le code à ne pas commenter.

Adapté de:

/programming/1030787/multiline-search-replace-with-perl


Merci pour votre aide, on dirait que c'est une douleur, j'ai décidé d'utiliser une solution de contournement
— Doug Molineux


1
  • /<\!--/ : chaîne correspondante
  • :X : c'est une étiquette pour la commande de branche "b"
  • /-->/ : chaîne correspondante
  • s@...@...@p : supprimer "<! -", "->" et imprimer le résultat
  • d : supprimer l'espace de motif et commencer un nouveau cycle
  • N : sinon correspondre avec / -> / puis ajouter une ligne
  • bX : branche vers: étiquette X
  • p : affiche simplement une chaîne qui ne correspond pas à / <! - /

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

et cette deuxième méthode est une simple substitution de copier-coller textuellement pour les fichiers texte habituels de petite taille (besoin d'un fichier de script shell)

#!/bin/bash

# copy & paste content that you want to substitute

AA=$( cat <<\EOF | sed -z -e 's#\([][^$*\.#]\)#\\\1#g' -e 's#\n#\\n#g'
<!--
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
-->
EOF
)

BB=$( cat <<\EOF | sed -z -e 's#\([&\#]\)#\\\1#g' -e 's#\n#\\n#g'
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
EOF
)

sed -z -i 's#'"${AA}"'#'"${BB}"'#g' *.xml   # apply to all *.xml files

1) Merci pour votre réponse. 2) L'insertion uniquement d'extraits de code n'est pas vraiment acceptable, il serait préférable que vous expliquiez ce qu'elle fait et comment.
— peterh
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.