Il modo portatile per farlo - e il modo più efficiente - è con gli indirizzi. Puoi farlo:
printf %s\\n cat dog pear banana cat dog |
sed -e '/cat/!{/dog/!b' -e '};cBear'
In questo modo, se la linea non contiene la stringa gatto e non contiene la stringa cane sed
b
ranch fuori dello script, autoprints la sua linea attuale e tira nel prossimo per iniziare il ciclo successivo. Pertanto non esegue le istruzioni successive, che in questo esempio c
impiccano l'intera riga per leggere Orso ma potrebbe fare qualsiasi cosa.
Probabilmente vale la pena notare anche che qualsiasi istruzione che segue il comando !b
in quel sed
comando può corrispondere solo su una riga contenente la stringa dog
o cat
- quindi è possibile eseguire ulteriori test senza il pericolo di abbinare una riga che non lo fa - il che significa che ora è possibile applicare le regole anche solo l'uno o l'altro.
Ma questo è il prossimo. Ecco l'output del comando sopra:
###OUTPUT###
Bear
Bear
pear
banana
Bear
Bear
È inoltre possibile implementare in modo portabile una tabella di ricerca con riferimenti indietro.
printf %s\\n cat dog pear banana cat dog |
sed '1{x;s/^/ cat dog /;x
};G;s/^\(.*\)\n.* \1 .*/Bear/;P;d'
È molto più complicato da configurare per questo semplice esempio, ma sed
a lungo termine può rendere gli script molto più flessibili .
Nella prima riga x
cambio spazio di mantenimento e spazio modello, quindi inserisco il cane <space>
gatto<space>
<space>
stringa nello spazio di attesa prima di x
cambiarlo indietro.
Da quel momento in poi e su ogni riga successiva I G
et hold spazio aggiunto allo spazio pattern, quindi controlla per vedere se tutti i caratteri dall'inizio della riga fino alla nuova riga che ho appena aggiunto alla fine corrispondono a una stringa circondata da spazi dopo di essa. In tal caso, sostituisco l'intero lotto con Orso e, in caso contrario, non viene fatto alcun danno, poiché successivamente P
rint solo fino alla prima nuova riga presente nello spazio modello, d
elimino tutto.
###OUTPUT###
Bear
Bear
pear
banana
Bear
Bear
E quando dico flessibile, intendo. Qui sta sostituendo il gatto con BrownBear e il cane con BlackBear :
printf %s\\n cat dog pear banana cat dog |
sed '1{x;s/^/ 1cat Brown 2dog Black /;x
};G;s/^\(.*\)\n.* [0-9]\1 \([^ ]*\) .*/\2Bear/;P;d'
###OUTPUT###
BrownBear
BlackBear
pear
banana
BrownBear
BlackBear
Ovviamente puoi espandere molto il contenuto della tabella di ricerca: ho preso l'idea dalle e -mail usenet di Greg Ubben sull'argomento quando, negli anni '90, ha descritto come ha costruito un calcolatore grezzo da una singola sed s///
affermazione.
-r
opzione come sinonimo di-E
compatibilità con GNU sed. OpenBSD e OS Xsed -E
interpreteranno la pipe di escape come una pipe letterale, non come un operatore di alternanza. Ecco un link funzionante alla pagina man di NetBSD ed eccone uno per OpenBSD che non ha dieci anni.