GNU/Linux >> Tutoriels Linux >  >> Linux

Remplacement SED sur plusieurs lignes

Solution 1 :

Sed fonctionne ligne par ligne. Il peut être conçu pour fonctionner sur plusieurs lignes, mais il n'a pas été conçu de cette façon - et à mon avis, cela se voit clairement lorsque vous essayez de l'utiliser comme ça. Mais si vous décidez de suivre cette voie, vous devrez probablement utiliser des registres. Vérifiez certaines des solutions sur https://stackoverflow.com/questions/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é multi-lignes, je veux dire). Le passe-partout que vous devez ajouter avant le rechercher-remplacer (BEGIN... ) n'est pas évident, mais la regex 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 vous permettre d'y utiliser une regex :

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

Cela devrait fonctionner à la fois sur les occurrences avec et sans retour à la ligne entre les marqueurs de commentaire et le code à décommenter.

Adapté de :

https://stackoverflow.com/questions/1030787/multiline-search-replace-with-perl

Solution 2 :

sed lit chaque ligne à tour de rôle, de sorte qu'il ne correspondra jamais à un modèle multiligne à moins que vous ne le poussiez dans la bonne direction. Le N La commande lit une ligne à partir de l'entrée et l'ajoute à l'espace du modèle.

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 , vous devez alors passer de sed à awk ou perl. Voici un extrait de code 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

Solution 3 :

Voici une description des commandes multilignes dans SED :http://docstore.mik.ua/orelly/unix/sedawk/ch06_01.htm

C'est une douleur dans le cul. Vous pouvez suivre les conseils d'Eduardo et utiliser perl -i -p -e à la place.

Solution 4 :

  • /<\!--/ :chaîne correspondante
  • :X :ceci est une étiquette pour la commande de branche "b"
  • /-->/ :chaîne correspondante
  • [email protected]@[email protected] :supprimer "" et afficher le résultat
  • d  :supprimer l'espace du motif et démarrer un nouveau cycle
  • N :si non match avec /-->/ puis ajouter une ligne
  • bX :branche vers :étiquette X
  • p :imprimez simplement une chaîne qui ne correspond pas à /