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
BSD sed GNU sed

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
GNU sed

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.


GNU sed

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 implementacji sed . W przypadku GNU sed , 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


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow