sed
Sostituzione
Ricerca…
Sostituzione usando le variabili di shell
Variabili all'interno apici '
non vengono espansi shell compatibili POSIX, quindi utilizzando una variabile shell in una sed
sostituzione richiede l'uso di virgolette "
invece di apici '
:
$ var="he"
$ echo "hello" | sed "s/$var/XX/"
XXllo
$ var="he"
$ echo "hello" | sed 's/$var/XX/'
hello
Prestare attenzione all'iniezione di comando durante la valutazione delle variabili:
$ var='./&/;x;w/etc/passwd
> x;s/he'
$ echo "hello" | sed "s/$var/XX/"
sed: /etc/passwd: Permission denied
Se quanto sopra è stato eseguito come root, l'output sarebbe stato indistinguibile dal primo esempio e il contenuto di /etc/passwd
verrebbe distrutto.
backreference
Usando le parentesi di escape, puoi definire un gruppo di cattura in un pattern che può essere riportato in differita nella stringa di sostituzione con \1
:
$ echo Hello world! | sed 's/\(Hello\) world!/\1 sed/'
Hello sed
Con più gruppi:
$ echo one two three | sed 's/\(one\) \(two\) \(three\)/\3 \2 \1/'
three two one
Quando si utilizzano le espressioni regolari estese (vedere Opzioni aggiuntive ) le parentesi eseguono il raggruppamento per impostazione predefinita e non devono essere sottoposte a escape:
$ echo one two three | sed -E 's/(one) (two) (three)/\3 \2 \1/'
three two one
Le parole composte da lettere, cifre e caratteri di sottolineatura possono essere abbinate usando l'espressione [[:alnum:]_]\{1,\}
:
$ echo Hello 123 reg_exp | sed 's/\([[:alnum:]_]\{1,\}\) \([[:alnum:]_]\{1,\}\) \([[:alnum:]_]\{1,\}\)/\3 \2 \1/'
reg_exp 123 Hello
La sequenza \w
è equivalente a [[:alnum:]_]
$ echo Hello 123 reg_exp | sed 's/\(\w\w*\) \(\w\w*\) \(\w\w*\)/\3 \2 \1/'
reg_exp 123 Hello
Utilizzando diversi delimitatori
La specifica di base di gruppo aperta POSIX / IEEE dice :
[2addr] s / BRE / sostituzione / bandiere
Sostituire la stringa di sostituzione per le istanze di BRE nello spazio modello. È possibile utilizzare qualsiasi carattere diverso da backslash o newline al posto di una barra per delimitare BRE e la sostituzione. All'interno del BRE e della sostituzione, il delimitatore BRE stesso può essere utilizzato come carattere letterale se è preceduto da una barra retroversa.
Ci sono casi in cui il delimitatore /
per la sostituzione di sed
è nella BRE o nella sostituzione, innescando errori come:
$ echo "2/3/4" | sed "s/2/3/X/"
sed: -e expression #1, char 7: unknown option to `s'
Per questo, possiamo usare diversi delimitatori come #
o _
o anche uno spazio:
$ echo "2/3/4" | sed "s#2/3#X#"
X/4
$ echo "2/3/4" | sed "s_2/3_X_"
X/4
$ echo "2/3/4" | sed "s 2/3 X "
X/4
Flag di pattern - sostituzione dell'occorrenza
Se vogliamo sostituire solo la prima occorrenza in una riga, usiamo sed
come al solito:
$ cat example
aaaaabbbbb
aaaaaccccc
aaaaaddddd
$ sed 's/a/x/' example
xaaaabbbbb
xaaaaccccc
xaaaaddddd
Ma cosa succede se vogliamo sostituire tutte le occorrenze?
Aggiungiamo semplicemente il flag g
pattern alla fine:
$ sed 's/a/x/g' example
xxxxxbbbbb
xxxxxccccc
xxxxxddddd
E se vogliamo sostituire un evento specifico, possiamo effettivamente specificare quale:
$ sed 's/a/x/3' example
aaxaabbbbb
aaxaaccccc
aaxaaddddd
/3
è la terza occorrenza.
Da info sed
, vedere il manuale di GNU sed per la versione online
lo standard POSIX non specifica cosa dovrebbe accadere quando si mischiano i modificatori
g
e NUMBER e attualmente non esiste un significato ampiamente condiviso su tutte le implementazioni dised
. Per GNUsed
, l'interazione è definita come: ignora le corrispondenze prima di NUMBERth, quindi abbina e sostituisci tutte le corrispondenze dal NUMBER su.
$ sed 's/b/y/2g' example
aaaaabyyyy
aaaaaccccc
aaaaaddddd
$ sed 's/c/z/g3' example
aaaaabbbbb
aaaaacczzz
aaaaaddddd