sed
Podstawienie
Szukaj…
Podstawienie za pomocą zmiennych powłoki
Zmienne wewnątrz pojedynczych cudzysłowów '
nie są rozszerzane przez powłoki zgodne z POSIX, więc użycie zmiennej powłoki w podstawieniu sed
wymaga użycia podwójnych cudzysłowów "
zamiast pojedynczych cudzysłowów '
:
$ var="he"
$ echo "hello" | sed "s/$var/XX/"
XXllo
$ var="he"
$ echo "hello" | sed 's/$var/XX/'
hello
Podczas oceny zmiennych należy zachować ostrożność podczas wprowadzania poleceń:
$ var='./&/;x;w/etc/passwd
> x;s/he'
$ echo "hello" | sed "s/$var/XX/"
sed: /etc/passwd: Permission denied
Gdyby powyższe zostało uruchomione jako root, wynik byłby nie do odróżnienia od pierwszego przykładu, a zawartość /etc/passwd
zostałaby zniszczona.
Odwołanie wsteczne
Za pomocą nawiasów zamkniętych można zdefiniować grupę przechwytywania we wzorcu, do którego można odwołać się ponownie w ciągu podstawiania za pomocą \1
:
$ echo Hello world! | sed 's/\(Hello\) world!/\1 sed/'
Hello sed
Z wieloma grupami:
$ echo one two three | sed 's/\(one\) \(two\) \(three\)/\3 \2 \1/'
three two one
Podczas korzystania z rozszerzonych wyrażeń regularnych (patrz Opcje dodatkowe ) nawiasy domyślnie wykonują grupowanie i nie trzeba ich zmieniać:
$ echo one two three | sed -E 's/(one) (two) (three)/\3 \2 \1/'
three two one
Słowa składające się z litery, cyfr i znaków podkreślenia można dopasować za pomocą wyrażenia [[:alnum:]_]\{1,\}
:
$ echo Hello 123 reg_exp | sed 's/\([[:alnum:]_]\{1,\}\) \([[:alnum:]_]\{1,\}\) \([[:alnum:]_]\{1,\}\)/\3 \2 \1/'
reg_exp 123 Hello
Sekwencja \w
jest równoważna z [[:alnum:]_]
$ echo Hello 123 reg_exp | sed 's/\(\w\w*\) \(\w\w*\) \(\w\w*\)/\3 \2 \1/'
reg_exp 123 Hello
Korzystanie z różnych ograniczników
POSIX / IEEE Open Group Base Specification mówi :
[2addr] s / BRE / replace / flags
Zastąp ciąg zastępujący wystąpieniami BRE w obszarze szyku. Można użyć dowolnego znaku innego niż ukośnik odwrotny lub znak nowej linii zamiast ukośnika, aby oddzielić BRE i zamiennik. W BRE i zamienniku sam ogranicznik BRE może być używany jako dosłowny znak, jeśli jest poprzedzony odwrotnym ukośnikiem.
Zdarzają się przypadki, gdy separator /
dla zamiany sed
znajduje się w BRE lub zamianie, powodując błędy, takie jak:
$ echo "2/3/4" | sed "s/2/3/X/"
sed: -e expression #1, char 7: unknown option to `s'
W tym celu możemy użyć różnych ograniczników, takich jak #
lub _
a nawet spacja:
$ 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
Flagi wzorca - zamiana wystąpienia
Jeśli chcemy zastąpić tylko pierwsze wystąpienie w linii, używamy sed
jak zwykle:
$ cat example
aaaaabbbbb
aaaaaccccc
aaaaaddddd
$ sed 's/a/x/' example
xaaaabbbbb
xaaaaccccc
xaaaaddddd
Ale co, jeśli chcemy zastąpić wszystkie wystąpienia?
Na końcu dodajemy flagę wzoru g
:
$ sed 's/a/x/g' example
xxxxxbbbbb
xxxxxccccc
xxxxxddddd
A jeśli chcemy zastąpić jedno konkretne wystąpienie, możemy faktycznie określić, które:
$ sed 's/a/x/3' example
aaxaabbbbb
aaxaaccccc
aaxaaddddd
/3
oznacza 3. wystąpienie.
Z info sed
, patrz instrukcja GNU sed dla wersji online
standard POSIX nie określa, co powinno się stać, gdy miksujesz modyfikatory
g
NUMBER, a obecnie nie ma powszechnie uzgodnionego znaczenia dla różnych implementacjised
. W przypadku GNUsed
, interakcja jest zdefiniowana jako: zignoruj dopasowania przed NUMBER, a następnie dopasuj i zamień wszystkie dopasowania z NUMBER.
$ sed 's/b/y/2g' example
aaaaabyyyy
aaaaaccccc
aaaaaddddd
$ sed 's/c/z/g3' example
aaaaabbbbb
aaaaacczzz
aaaaaddddd