Edytor strumienia - ciągi

Zastępcza komenda

Operacje zastępowania tekstu, takie jak „znajdź i zamień”, są powszechne w każdym edytorze tekstu. W tej sekcji zilustrujemy, w jaki sposób SED wykonuje podstawianie tekstu. Poniżej podano składnię polecenia substytucji.

[address1[,address2]]s/pattern/replacement/[flags]

Tutaj, address1 i address2są odpowiednio adresami początkowymi i końcowymi, którymi mogą być numery wierszy lub łańcuchy wzorów. Oba te adresy są parametrami opcjonalnymi. Wzorzec to tekst, który chcemy zastąpić ciągiem zastępczym. Dodatkowo możemy określić opcjonalne flagi w SED.

W pliku books.txt użyliśmy przecinka (,) do oddzielenia każdej kolumny. Użyjmy pionowej kreski (|), aby oddzielić każdą kolumnę. Aby to zrobić, zamień przecinek (,) na pionową kreskę (|).

[jerry]$ sed 's/,/ | /' books.txt

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

1) A Storm of Swords | George R. R. Martin, 1216 
2) The Two Towers | J. R. R. Tolkien, 352 
3) The Alchemist | Paulo Coelho, 197 
4) The Fellowship of the Ring | J. R. R. Tolkien, 432 
5) The Pilgrimage | Paulo Coelho, 288 
6) A Game of Thrones | George R. R. Martin, 864

Jeśli będziesz uważnie obserwować, tylko pierwszy przecinek zostanie zastąpiony, a drugi pozostanie bez zmian. Czemu? Gdy tylko wzór pasuje, SED zastępuje go ciągiem zastępczym i przechodzi do następnej linii. Domyślnie zastępuje tylko pierwsze wystąpienie. Aby zamienić wszystkie wystąpienia, użyj flagi globalnej (g) z SED w następujący sposób:

[jerry]$ sed 's/,/ | /g' books.txt

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

1) A Storm of Swords | George R. R. Martin | 1216 
2) The Two Towers | J. R. R. Tolkien | 352 
3) The Alchemist | Paulo Coelho | 197 
4) The Fellowship of the Ring | J. R. R. Tolkien | 432 
5) The Pilgrimage | Paulo Coelho | 288 
6) A Game of Thrones | George R. R. Martin | 864

Teraz wszystkie wystąpienia przecinków (,) są zastępowane pionową kreską (|).

Możemy poinstruować SED, aby wykonywał podstawianie tekstu tylko wtedy, gdy dopasowanie wzorca powiedzie się. Poniższy przykład zastępuje przecinek (,) pionową kreską (|) tylko wtedy, gdy wiersz zawiera wzorzec Pielgrzymka.

[jerry]$ sed '/The Pilgrimage/ s/,/ | /g' books.txt

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

1) A Storm of Swords, George R. R. Martin, 1216 
2) The Two Towers, J. R. R. Tolkien, 352 
3) The Alchemist, Paulo Coelho, 197 
4) The Fellowship of the Ring, J. R. R. Tolkien, 432 
5) The Pilgrimage | Paulo Coelho | 288 
6) A Game of Thrones, George R. R. Martin, 864

Oprócz tego SED może zastąpić określone wystąpienie wzorca. Zastąpmy tylko drugie wystąpienie przecinka (,) pionową kreską (|).

[jerry]$ sed 's/,/ | /2' books.txt

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

1) A Storm of Swords, George R. R. Martin | 1216 
2) The Two Towers, J. R. R. Tolkien | 352 
3) The Alchemist, Paulo Coelho | 197 
4) The Fellowship of the Ring, J. R. R. Tolkien | 432 
5) The Pilgrimage,Paulo Coelho | 288 
6) A Game of Thrones, George R. R. Martin  | 864

W powyższym przykładzie liczba na końcu polecenia SED (lub w miejscu flagi) oznacza drugie wystąpienie.

SED zapewnia interesującą funkcję. Po wykonaniu zamiany SED zapewnia opcję pokazania tylko zmienionych wierszy. W tym celu SED używa rozszerzeniapflaga odnosząca się do druku. Poniższy przykład zawiera tylko zmienione wiersze.

[jerry]$ sed -n 's/Paulo Coelho/PAULO COELHO/p' books.txt

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

3) The Alchemist, PAULO COELHO, 197 
5) The Pilgrimage, PAULO COELHO, 288

Możemy również przechowywać zmienione linie w innym pliku. Aby osiągnąć ten wynik, użyjwflaga. Poniższy przykład pokazuje, jak to zrobić.

[jerry]$ sed -n 's/Paulo Coelho/PAULO COELHO/w junk.txt' books.txt

Użyliśmy tego samego polecenia SED. Zweryfikujmy zawartość plikujunk.txt plik.

[jerry]$ cat junk.txt

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

3) The Alchemist, PAULO COELHO, 197 
5) The Pilgrimage, PAULO COELHO, 288

Aby wykonać podstawianie bez uwzględniania wielkości liter, użyj flagi i, która implikuje ignorowanie wielkości liter. Poniższy przykład wykonuje podstawianie bez uwzględniania wielkości liter.

[jerry]$ sed  -n 's/pAuLo CoElHo/PAULO COELHO/pi' books.txt

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

3) The Alchemist, PAULO COELHO, 197 
5) The Pilgrimage, PAULO COELHO, 288

Do tej pory jako separatora używaliśmy tylko znaku przedniego ukośnika (/), ale jako separatora możemy również użyć pionowej kreski (|), znaku (@), daszka (^), wykrzyknika (!). Poniższy przykład pokazuje, jak używać innych znaków jako separatora.

Załóżmy, że musisz wymienić ścieżkę /bin/sed z /home/jerry/src/sed/sed-4.2.2/sed. Dlatego polecenie SED wygląda następująco:

[jerry]$ echo "/bin/sed" | sed 's/\/bin\/sed/\/home\/jerry\/src\/sed\/sed-4.2.2\/sed/'

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

/home/jerry/src/sed/sed-4.2.2/sed

Możemy uczynić to polecenie bardziej czytelnym i łatwiejszym do zrozumienia. Użyjmy pionowej kreski (|) jako separatora i zobaczmy wynik.

[jerry]$ echo "/bin/sed" | sed 's|/bin/sed|/home/jerry/src/sed/sed-4.2.2/sed|'

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

/home/jerry/src/sed/sed-4.2.2/sed

W rzeczy samej! Otrzymaliśmy ten sam wynik, a składnia jest bardziej czytelna. Podobnie możemy użyć znaku „at” (@) jako separatora w następujący sposób:

[jerry]$ echo "/bin/sed" | sed 's@/bin/sed@/home/jerry/src/sed/sed-4.2.2/sed@'

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

/home/jerry/src/sed/sed-4.2.2/sed

Oprócz tego jako separatora możemy użyć daszka (^).

[jerry]$ echo "/bin/sed" | sed 's^/bin/sed^/home/jerry/src/sed/sed-4.2.2/sed^'

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

/home/jerry/src/sed/sed-4.2.2/sed

Jako separatora możemy również użyć wykrzyknika (!) W następujący sposób:

[jerry]$ echo "/bin/sed" | sed 's!/bin/sed!/home/jerry/src/sed/sed-4.2.2/sed!'

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

/home/jerry/src/sed/sed-4.2.2/sed

Zwykle jako separatora używany jest ukośnik odwrotny (/), ale czasami wygodniej jest użyć innych obsługiwanych separatorów z SED.

Tworzenie podłańcucha

Nauczyliśmy się potężnego polecenia zastępczego. Sprawdźmy, czy uda nam się znaleźć podciąg z dopasowanego tekstu. Zrozummy, jak to zrobić na przykładzie.

Rozważmy następujący tekst:

[jerry]$ echo "Three One Two"

Załóżmy, że musimy ułożyć to w sekwencję. Oznacza to, że powinien najpierw wypisać jeden, potem dwa, a na końcu trzy. Poniższa jednolinijka spełnia wszystkie wymagania.

echo "Three One Two" | sed 's|\(\w\+\) \(\w\+\) \(\w\+\)|\2 \3 \1|'

Zauważ, że w powyższym przykładzie pionowa kreska (|) jest używana jako separator.

W SED podciągi można określić za pomocą operatora grupowania i muszą być poprzedzone znakiem zmiany znaczenia, tj. \( i \).

\wto wyrażenie regularne pasujące do dowolnej litery, cyfry lub podkreślenia, a znak „+” służy do dopasowania więcej niż jednego znaku. Innymi słowy, wyrażenie regularne\(\w\+\) dopasowuje pojedyncze słowo z ciągu wejściowego.

W ciągu wejściowym znajdują się trzy słowa oddzielone spacją, stąd są threewyrażenia regularne oddzielone spacją. Pierwsze wyrażenie regularne przechowuje pierwsze słowo, tj. Three, drugie zapisuje słowoOnea trzecia przechowuje słowo Two

Te podciągi są określane przez \N,gdzie N jest numerem podciągu. W związku z tym,\2 drukuje drugi podciąg, tj. One; \3 drukuje trzeci podciąg, tj. Two; i \1 drukuje pierwszy podciąg, tj. Three

Oddzielmy te słowa przecinkami (,) i odpowiednio zmodyfikujmy wyrażenie regularne.

[jerry]$ echo "Three,One,Two" | sed 's|\(\w\+\),\(\w\+\),\(\w\+\)|\2,\3,\1|'

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

One,Two,Three

Zauważ, że teraz w wyrażeniu regularnym zamiast spacji jest przecinek (,).

Flagi zastępujące strun (tylko GNU SED)

W poprzedniej sekcji widzieliśmy kilka przykładów polecenia substytucji. GNU SED zapewnia pewne specjalne sekwencje specjalne, których można użyć w łańcuchu zastępczym. Należy zauważyć, że te flagi zastępujące ciąg są specyficzne dla GNU i mogą nie działać z innymi wariantami SED. Tutaj omówimy flagi zastępujące ciąg.

  • \ L: Gdy \ L jest określony w łańcuchu zastępującym, wszystkie pozostałe znaki słowa po \ L są traktowane jako małe litery. Na przykład znaki „ULO” są traktowane jako małe litery.

[jerry]$ sed -n 's/Paulo/PA\LULO/p' books.txt

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

3) The Alchemist, PAulo Coelho, 197
5) The Pilgrimage, PAulo Coelho, 288
  • \ u: Kiedy \ u jest określony w łańcuchu zastępującym, traktuje znak znajdujący się bezpośrednio po \ u jako wielką literę. W poniższym przykładzie \ u jest używane przed znakami „a” i „o”. Dlatego SED traktuje te znaki jako wielkie litery.

[jerry]$ sed -n 's/Paulo/p\uaul\uo/p' books.txt

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

3) The Alchemist, pAulO Coelho, 197 
5) The Pilgrimage, pAulO Coelho, 288
  • \ U: Gdy \ U jest określony w ciągu zastępującym, wszystkie pozostałe znaki słowa po \ U są traktowane jako wielkie litery.

[jerry]$ sed -n 's/Paulo/\Upaulo/p' books.txt

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

3) The Alchemist, PAULO Coelho, 197 
5) The Pilgrimage, PAULO Coelho, 288
  • \ E: Ta flaga powinna być używana z \ L lub \ U. Zatrzymuje konwersję zainicjowaną przez flagę \ L lub \ U. W poniższym przykładzie tylko pierwsze słowo jest zastępowane wielkimi literami.

[jerry]$ sed -n 's/Paulo Coelho/\Upaulo \Ecoelho/p' books.txt

Po wykonaniu powyższego kodu otrzymasz następujący wynik:

3) The Alchemist, PAULO coelho, 197 
5) The Pilgrimage, PAULO coelho, 288