Trois sed
commandes différentes :
sed '$!N;s/"[^"]*"\n<[^>]*>/other characters /;P;D'
sed -e :n -e '$!N;s/"[^"]*"\n<[^>]*>/other characters /;tn'
sed -e :n -e '$!N;/"$/{$!bn' -e '};s/"[^"]*"\n<[^>]*>/other characters /g'
Ils s'appuient tous les trois sur la s///
commande de base d' ubstitution:
s/"[^"]*"\n<[^>]*>/other characters /
Ils essaient également tous de faire attention dans leur traitement de la dernière ligne, car les sed
s ont tendance à différer sur leur sortie dans les cas de bord. Il s'agit de la signification d' $!
une adresse correspondant à chaque ligne qui n'est !
pas la $
dernière.
Ils utilisent également tous la N
commande ext pour ajouter la ligne d'entrée suivante à l'espace de motif à la suite d'un \n
caractère ewline. Quiconque travaille sed
depuis un certain temps aura appris à se fier au \n
caractère ewline - car la seule façon de l'obtenir est de le mettre explicitement là.
Tous les trois essaient de lire le moins d'entrées possible avant d'agir - sed
agissent dès que possible et n'ont pas besoin de lire l'intégralité d'un fichier d'entrée avant de le faire.
Bien qu'ils fassent tout N
, ils diffèrent tous les trois dans leurs méthodes de récursivité.
Première commande
La première commande utilise une N;P;D
boucle très simple . Ces trois commandes sont intégrées à tout compatible POSIX sed
et se complètent bien.
N
- comme déjà mentionné, ajoute la N
ligne d'entrée ext à l'espace de motif après un \n
délimiteur ewline inséré .
P
- comme p
; il P
imprime l'espace de motif - mais uniquement jusqu'au premier \n
caractère de ligne électronique apparaissant . Et donc, étant donné l'entrée / commande suivante:
printf %s\\n one two | sed '$!N;P;d'
sed
P
rints seulement un . Cependant, avec ...
D
- comme d
; il D
supprime l'espace modèle et commence un autre cycle linéaire. Contrairement à d
, D
ne supprime que jusqu'à la première ligne \n
électronique apparaissant dans l'espace de motif. S'il y a plus dans l'espace de motif suivant le \n
caractère ewline, sed
commence le cycle de ligne suivant avec ce qui reste. Si le d
dans l'exemple précédent ont été remplacés par un D
, par exemple, sed
serait P
Rint à la fois un et deux .
Cette commande ne se reproduit que pour les lignes qui ne correspondent pas à l' s///
instruction d'ubstitution. Étant donné que l' s///
ubstitution supprime la ligne \n
électronique ajoutée avec N
, il ne reste plus rien lorsqu'il sed
D
supprime l'espace de motif.
Des tests pourraient être effectués pour appliquer le P
et / ou de D
manière sélective, mais il existe d'autres commandes qui correspondent mieux à cette stratégie. Parce que la récursivité est implémentée pour gérer des lignes consécutives qui ne correspondent qu'à une partie de la règle de remplacement, les séquences consécutives de lignes correspondant aux deux extrémités de l' s///
ubstitution ne fonctionnent pas bien .:
Compte tenu de cette entrée:
first "line"
<second>"line"
<second>"line"
<second>line and so on
... ça imprime ...
first other characters "line"
<second>other characters line and so on
Il gère cependant
first "line"
second "line"
<second>line
...ça va.
Deuxième commande
Cette commande est très similaire à la troisième. Les deux utilisent une étiquette :b
ranch / t
est (comme cela est également démontré dans la réponse de Joeseph R. ici ) et y reviennent dans certaines conditions.
-e :n -e
- les sed
scripts portables délimiteront une :
définition d'étiquette avec une ligne \n
électronique ou une nouvelle -e
instruction d'exécution en ligne .
:n
- définit une étiquette nommée n
. Cela peut être retourné à tout moment avec bn
ou tn
.
tn
- la t
commande est retourne à une étiquette spécifiée (ou, si aucune n'est fournie, quitte le script pour le cycle de ligne en cours) si toute s///
substitution depuis que l'étiquette a été définie ou depuis qu'elle a été appelée pour la dernière fois t
ests a réussi.
Dans cette commande, la récursivité se produit pour les lignes correspondantes. Si sed
le modèle est remplacé avec succès par d' autres caractères , sed
retourne à l' :n
étiquette et réessaye. Si s///
aucune substitution n'est effectuée, l' sed
impression automatique de l'espace de motif commence le cycle de ligne suivant.
Cela a tendance à mieux gérer les séquences consécutives. Là où le dernier a échoué, cela affiche:
first other characters other characters other characters line and so on
Troisième commande
Comme mentionné, la logique ici est très similaire à la dernière, mais le test est plus explicite.
/"$/bn
- c'est sed
le test. Parce que la b
commande ranch est fonction de cette adresse, sed
ne fera que b
revenir ranch à la :n
suite d' un \n
ewline est ajouté et la structure de l' espace se termine toujours avec un "
guillemet.
Il y a aussi peu de choses à faire entre N
et b
que possible - de cette manière, vous sed
pouvez très rapidement rassembler exactement autant de données que nécessaire pour vous assurer que la ligne suivante ne correspond pas à votre règle. L' s///
ubstitution diffère ici en ce qu'elle utilise le g
drapeau lobal - et donc elle fera tous les remplacements nécessaires à la fois. Pour une entrée identique, cette commande est identique à la dernière.
\n
déclaration ewline que vous faites est pourquoi je demande. les gens demandent rarement s'ils peuvent faire ces//\n/
que vous pouvez faire avec GNUsed
, bien que la plupart des autressed
rejetteront cette fuite du côté droit. néanmoins, l'\n
échappement fonctionnera à gauche dans n'importe quel POSIXsed
et vous pouvez les traduire de manière portable commey/c/\n/
si cela aurait le même effets/c/\n/g
et n'est donc pas toujours aussi utile.