sed
Utbyte
Sök…
Ersättning med hjälp av skalvariabler
Variabler i enstaka citat '
utvidgas inte med POSIX-kompatibla skal, så att man använder en skalvariabel i en sed
substitution kräver användning av dubbla citat "
istället för enstaka citat '
:
$ var="he"
$ echo "hello" | sed "s/$var/XX/"
XXllo
$ var="he"
$ echo "hello" | sed 's/$var/XX/'
hello
Var försiktig med kommandoinjektion när du utvärderar variabler:
$ var='./&/;x;w/etc/passwd
> x;s/he'
$ echo "hello" | sed "s/$var/XX/"
sed: /etc/passwd: Permission denied
Om ovanstående kördes som root skulle utgången vara oskiljbar från det första exemplet och innehållet i /etc/passwd
skulle förstöras.
bakåtreferens
Med hjälp av undvikna parenteser kan du definiera en fångargrupp i ett mönster som kan återrefereras i substitutionssträngen med \1
:
$ echo Hello world! | sed 's/\(Hello\) world!/\1 sed/'
Hello sed
Med flera grupper:
$ echo one two three | sed 's/\(one\) \(two\) \(three\)/\3 \2 \1/'
three two one
När du använder utökade reguljära uttryck (se Ytterligare alternativ ) utför parenteser gruppering som standard och behöver inte undkomma:
$ echo one two three | sed -E 's/(one) (two) (three)/\3 \2 \1/'
three two one
Ord som består av bokstäver, siffror och understreck kan matchas med uttrycket [[:alnum:]_]\{1,\}
:
$ echo Hello 123 reg_exp | sed 's/\([[:alnum:]_]\{1,\}\) \([[:alnum:]_]\{1,\}\) \([[:alnum:]_]\{1,\}\)/\3 \2 \1/'
reg_exp 123 Hello
Sekvensen \w
är ekvivalent med [[:alnum:]_]
$ echo Hello 123 reg_exp | sed 's/\(\w\w*\) \(\w\w*\) \(\w\w*\)/\3 \2 \1/'
reg_exp 123 Hello
Använda olika avgränsare
POSIX / IEEE Open Group Base Specification säger :
[2addr] s / BRE / ersättning / flaggor
Ersätt ersättningssträngen för instanser av BRE i mönsterutrymmet. Alla andra tecken än backslash eller newline kan användas istället för en snedstreck för att avgränsa BRE och ersättningen. Inom BRE och ersättningen kan själva BRE-avgränsaren användas som en bokstavlig karaktär om den föregås av ett motstreck.
Det finns fall då avgränsaren /
för sed
ersättningen är i BRE eller ersättningen, vilket utlöser fel som:
$ echo "2/3/4" | sed "s/2/3/X/"
sed: -e expression #1, char 7: unknown option to `s'
För detta kan vi använda olika avgränsare som #
eller _
eller till och med ett mellanslag:
$ 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
Mönsterflaggor - händelseersättning
Om vi bara vill ersätta den första händelsen i en rad använder vi sed
som vanligt:
$ cat example
aaaaabbbbb
aaaaaccccc
aaaaaddddd
$ sed 's/a/x/' example
xaaaabbbbb
xaaaaccccc
xaaaaddddd
Men tänk om vi vill ersätta alla händelser?
Vi lägger bara till g
mönsterflaggan i slutet:
$ sed 's/a/x/g' example
xxxxxbbbbb
xxxxxccccc
xxxxxddddd
Och om vi vill ersätta en specifik händelse, kan vi faktiskt ange vilken:
$ sed 's/a/x/3' example
aaxaabbbbb
aaxaaccccc
aaxaaddddd
/3
är den tredje förekomsten.
Från info sed
, se GNU sed manual för onlineversion
POSIX-standarden specificerar inte vad som ska hända när du blandar
g
och NUMMER-modifierare, och för närvarande finns det inte någon överenskommelse som är allmänt överens om översed
implementeringar. För GNU-sed
definieras interaktionen som: ignorera matchningar före NUMBER: e och matcha sedan och ersätt alla matchningar från NUMBER: e.
$ sed 's/b/y/2g' example
aaaaabyyyy
aaaaaccccc
aaaaaddddd
$ sed 's/c/z/g3' example
aaaaabbbbb
aaaaacczzz
aaaaaddddd