Sed: Utilisation de a, c ou i dans un one-liner

J’utilise souvent a et i dans les scripts sed, mais comment les utiliser généralement dans un one-liner (ou plus spécifiquement pour signifier la fin du texte)?

J’ai essayé de citer le texte, en ajoutant un nouveau caractère de ligne pour indiquer la fin du texte, échappant à la nouvelle ligne; rien ne fonctionne, sed traite simplement tous les caractères à la fin de la ligne du shell en tant que texte avec lequel travailler.

Cela pose un problème lorsque vous avez d’autres actions à suivre, car elles sont traitées comme du texte et non comme des commandes pour sed, telles que p.

C’est bon:

/RANGE_start/,/RANGE_end/{ s/foo/bar/ /RANGE_end/a \--- This is the end of the range block --- p } 

Cela ne fonctionne pas bien:

 /RANGE_start/,/RANGE_end/{s/foo/bar/;/RANGE_end/a \--- This is the end of the range block ---; p} 

où le résultat est

— Ceci est la fin du bloc d’intervalle —; p}

ou, comme j’essaie d’utiliser p, pas de sortie (en supposant que sed a été démarré avec -n).

Y a-t-il un caractère spécial que je peux passer à a, c et i pour signifier la fin du texte?

(BTW, il ne s’agit pas seulement de lignes à une ligne, (dans une autre question que je pose), il s’agit également d’écrire dans un fichier en utilisant w où le texte n’est pas écrit dans le fichier.)

[Je soupçonne que j’utilise certains détails Gnu ci-dessus.]

Essayez-vous de remplacer foo par une barre dans une plage et imprimez du texte à la fin de la plage? Avec awk, vous POUVEZ écrire ceci en utilisant des plages comme vous devez le faire:

 awk ' /RANGE_start/,/RANGE_end/ { sub(/foo/,"bar") print if (/RANGE_end/) { print "--- This is the end of the range block ---" } } ' 

mais awk vous permet également d’utiliser des variables à la place, de sorte que vous ne soyez pas confronté aux conditions de duplication requirejses lors de l’utilisation de plages (notez que RANGE_end n’est testé qu’une fois dans le script ci-dessous):

 awk ' /RANGE_start/ { inRange = 1 } inRange { sub(/foo/,"bar") print if (/RANGE_end/) { print "--- This is the end of the range block ---" inRange = 0 } } ' 

Compte tenu de cette idée de manipulation des plages en utilisant un indicateur pour indiquer quand vous êtes dans la plage, regardez comme il est simple de sélectionner l’impression des lignes de début / fin de plage (ou autre chose!) En changeant simplement :

 $ seq 1 10 | awk '/3/{f=1} f{print} /7/{f=0}' 3 4 5 6 7 $ seq 1 10 | awk 'f{print} /3/{f=1} /7/{f=0}' 4 5 6 7 $ seq 1 10 | awk '/3/{f=1} /7/{f=0} f{print}' 3 4 5 6 $ seq 1 10 | awk '/7/{f=0} f{print} /3/{f=1}' 4 5 6 

sed est idéal pour les substitutions simples sur des lignes individuelles, mais pour toute autre chose, vous devriez utiliser awk pour plus de clarté, de simplicité, d’efficacité, de portabilité et pour la plupart des autres atsortingbuts logiciels souhaitables.