Unix / Linux - wyrażenia regularne z SED

W tym rozdziale omówimy szczegółowo wyrażenia regularne z SED w systemie Unix.

Wyrażenie regularne to ciąg, którego można użyć do opisania kilku sekwencji znaków. Wyrażenia regularne są używane przez kilka różnych poleceń systemu Unix, w tymed, sed, awk, grepi w bardziej ograniczonym zakresie, vi.

Tutaj SED oznacza stream editor. Ten edytor strumieniowy został stworzony wyłącznie do wykonywania skryptów. W ten sposób wszystkie dane wejściowe, które do niego wprowadzasz, przechodzą i trafiają do STDOUT i nie zmieniają pliku wejściowego.

Wzywając sed

Zanim zaczniemy, upewnijmy się, że mamy lokalną kopię pliku /etc/passwd plik tekstowy do pracy sed.

Jak wspomniano wcześniej, sed można wywołać, wysyłając do niego dane przez potok w następujący sposób -

$ cat /etc/passwd | sed
Usage: sed [OPTION]... {script-other-script} [input-file]...

  -n, --quiet, --silent
                 suppress automatic printing of pattern space
  -e script, --expression = script
...............................

Plik cat polecenie zrzuca zawartość /etc/passwd do sedprzez rurę do przestrzeni wzorcowej seda. Przestrzeń wzorców to wewnętrzny bufor roboczy, którego sed używa do swoich operacji.

Ogólna składnia seda

Poniżej znajduje się ogólna składnia sed -

/pattern/action

Tutaj, pattern jest wyrażeniem regularnym, a actionjest jednym z poleceń podanych w poniższej tabeli. Gdybypattern jest pominięty, action jest wykonywana dla każdej linii, jak widzieliśmy powyżej.

Ukośnik (/) otaczający wzór jest wymagany, ponieważ jest używany jako ograniczniki.

Sr.No. Zakres i opis
1

p

Drukuje linię

2

d

Usuwa linię

3

s/pattern1/pattern2/

Zastępuje pierwsze wystąpienie wzorzec1 wzorem2

Usuwanie wszystkich linii za pomocą sed

Teraz zrozumiemy, jak usunąć wszystkie linie za pomocą seda. Przywołaj ponownie seda; ale sed powinien teraz używać rozszerzeniaediting command delete line, oznaczony jedną literą d -

$ cat /etc/passwd | sed 'd'
$

Zamiast wywoływać seda przez wysłanie do niego pliku przez potok, sed można poinstruować, aby odczytał dane z pliku, jak w poniższym przykładzie.

Następujące polecenie działa dokładnie tak samo, jak w poprzednim przykładzie, bez polecenia cat -

$ sed -e 'd' /etc/passwd
$

Sed Adresy

Sed obsługuje również adresy. Adresy to określone lokalizacje w pliku lub zakres, w którym należy zastosować określone polecenie edycji. Kiedy sed nie napotyka żadnych adresów, wykonuje swoje operacje na każdej linii w pliku.

Następujące polecenie dodaje podstawowy adres do polecenia sed, którego używasz -

$ cat /etc/passwd | sed '1d' |more
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
$

Zauważ, że liczba 1 jest dodawana przed delete editKomenda. Nakazuje sedowi wykonanie polecenia edycji w pierwszym wierszu pliku. W tym przykładzie sed usunie pierwszą linię/etc/password i wydrukuj pozostałą część pliku.

Zakresy adresów seda

Teraz zrozumiemy, jak pracować z the sed address ranges. A co jeśli chcesz usunąć więcej niż jedną linię z pliku? Możesz określić zakres adresów za pomocą seda w następujący sposób -

$ cat /etc/passwd | sed '1, 5d' |more
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
$

Powyższe polecenie zostanie zastosowane do wszystkich linii zaczynających się od 1 do 5. Spowoduje to usunięcie pierwszych pięciu linii.

Wypróbuj następujące zakresy adresów -

Sr.No. Zakres i opis
1

'4,10d'

Linie zaczynające się od 4 th do 10 th są usuwane

2

'10,4d'

Tylko 10 th linia zostanie usunięty, ponieważ sed nie działa w odwrotnym kierunku

3

'4,+5d'

To dopasowuje wiersz 4 w pliku, usuwa ten wiersz, kontynuuje usuwanie kolejnych pięciu wierszy, a następnie zaprzestaje jego usuwania i drukuje resztę

4

'2,5!d'

To wszystko Usuwa z wyjątkiem począwszy od 2 ND do 5 th linii

5

'1~3d'

Spowoduje to usunięcie pierwszej linii, przejście przez następne trzy linie, a następnie usunięcie czwartej linii. Sed kontynuuje stosowanie tego wzorca do końca pliku.

6

'2~2d'

To każe sedowi usunąć drugą linię, przejść przez następną linię, usunąć następną linię i powtarzać aż do końca pliku

7

'4,10p'

Linie wychodząc z 4 TH do 10 p są drukowane

8

'4,d'

To generuje błąd składni

9

',10d'

Spowodowałoby to również błąd składni

Note - Podczas korzystania z p działania, powinieneś użyć -nopcja pozwalająca uniknąć powtórzeń drukowania linii. Sprawdź różnicę między następującymi dwoma poleceniami -

$ cat /etc/passwd | sed -n '1,3p'
Check the above command without -n as follows −
$ cat /etc/passwd | sed '1,3p'

Komenda podstawienia

Polecenie podstawienia, oznaczone s, zastąpi dowolny określony ciąg dowolnym innym określonym przez Ciebie.

Aby zamienić jeden ciąg na inny, sed musi mieć informacje o tym, gdzie kończy się pierwszy łańcuch, a zaczyna zastępowany łańcuch. W tym celu kontynuujemy zapisywanie dwóch ciągów za pomocą ukośnika (/) postać.

Następujące polecenie zastępuje pierwsze wystąpienie w wierszu ciągu root ze sznurkiem amrood.

$ cat /etc/passwd | sed 's/root/amrood/'
amrood:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
..........................

Bardzo ważne jest, aby pamiętać, że sed zastępuje tylko pierwsze wystąpienie w linii. Jeśli pierwiastek ciągu występuje więcej niż raz w wierszu, tylko pierwsze dopasowanie zostanie zastąpione.

Aby sed mógł wykonać globalne podstawienie, dodaj literę g do końca polecenia w następujący sposób -

$ cat /etc/passwd | sed 's/root/amrood/g'
amrood:x:0:0:amrood user:/amrood:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
...........................

Flagi zmiany

Istnieje wiele innych przydatnych flag, które można przekazać oprócz g flagę i możesz określić więcej niż jedną naraz.

Sr.No. Flaga i opis
1

g

Zastępuje wszystkie dopasowania, a nie tylko pierwsze dopasowanie

2

NUMBER

Zastępuje tylko NUMBER- te dopasowanie

3

p

Jeśli dokonano podstawienia, drukuje przestrzeń wzoru

4

w FILENAME

Jeśli dokonano podstawienia, zapisuje wynik do FILENAME

5

I or i

Dopasowuje bez rozróżniania wielkości liter

6

M or m

Oprócz normalnego zachowania znaków ^ i $ specjalnego wyrażenia regularnego ta flaga powoduje, że ^ dopasowuje pusty ciąg po nowej linii, a znak $ dopasowuje pusty ciąg przed nową linią

Korzystanie z alternatywnego separatora ciągów

Załóżmy, że musisz wykonać podstawienie w ciągu zawierającym ukośnik. W takim przypadku możesz określić inny separator, podając wyznaczony znak pos.

$ cat /etc/passwd | sed 's:/root:/amrood:g'
amrood:x:0:0:amrood user:/amrood:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh

W powyższym przykładzie użyliśmy : jako delimiter zamiast ukośnika / ponieważ próbowaliśmy wyszukiwać /root zamiast prostego roota.

Zastąpienie pustą przestrzenią

Użyj pustego ciągu podstawienia, aby usunąć ciąg główny z pliku /etc/passwd plik całkowicie -

$ cat /etc/passwd | sed 's/root//g'
:x:0:0::/:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh

Zastępowanie adresu

Jeśli chcesz zastąpić ciąg sh ze sznurkiem quiet tylko w linii 10, możesz to określić następująco -

$ cat /etc/passwd | sed '10s/sh/quiet/g'
root:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/quiet

Podobnie, aby dokonać podstawienia zakresu adresów, możesz zrobić coś takiego:

$ cat /etc/passwd | sed '1,5s/sh/quiet/g'
root:x:0:0:root user:/root:/bin/quiet
daemon:x:1:1:daemon:/usr/sbin:/bin/quiet
bin:x:2:2:bin:/bin:/bin/quiet
sys:x:3:3:sys:/dev:/bin/quiet
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh

Jak widać na wyjściu, pierwsze pięć wierszy zawierało ciąg sh zmienić na quiet, ale reszta linii pozostała nietknięta.

Dopasowanie polecenia

Używałbyś p opcja wraz z -n opcja drukowania wszystkich pasujących wierszy w następujący sposób -

$ cat testing | sed -n '/root/p'
root:x:0:0:root user:/root:/bin/sh
[root@ip-72-167-112-17 amrood]# vi testing
root:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh

Używanie wyrażeń regularnych

Dopasowując wzorce, możesz użyć wyrażenia regularnego, które zapewnia większą elastyczność.

Sprawdź poniższy przykład, który pasuje do wszystkich linii zaczynających się od daemon, a następnie je usuwa -

$ cat testing | sed '/^daemon/d'
root:x:0:0:root user:/root:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh

Poniżej znajduje się przykład, który usuwa wszystkie wiersze kończące się na sh -

$ cat testing | sed '/sh$/d'
sync:x:4:65534:sync:/bin:/bin/sync

W poniższej tabeli wymieniono cztery znaki specjalne, które są bardzo przydatne w wyrażeniach regularnych.

Sr.No. Opis postaci
1

^

Odpowiada początkowi wierszy

2

$

Dopasowuje koniec wierszy

3

.

Dopasowuje dowolny pojedynczy znak

4

*

Dopasowuje zero lub więcej wystąpień poprzedniego znaku

5

[chars]

Dopasowuje dowolny ze znaków podanych w chars, gdzie chars jest sekwencją znaków. Możesz użyć znaku -, aby wskazać zakres znaków.

Pasujące znaki

Spójrz na kilka innych wyrażeń, aby zademonstrować użycie metacharacters. Na przykład następujący wzór -

Sr.No. Wyrażenie i opis
1

/a.c/

Dopasowuje wiersze zawierające ciągi, takie jak a+c, a-c, abc, match, i a3c

2

/a*c/

Dopasowuje te same ciągi wraz z ciągami, takimi jak ace, yacc, i arctic

3

/[tT]he/

Pasuje do ciągu The i the

4

/^$/

Dopasowuje puste linie

5

/^.*$/

Dopasowuje całą linię, cokolwiek to jest

6

/ */

Odpowiada co najmniej jednej spacji

7

/^$/

mecze blank linie

Poniższa tabela przedstawia niektóre często używane zestawy znaków -

Sr.No. Ustaw i opis
1

[a-z]

Dopasowuje pojedynczą małą literę

2

[A-Z]

Dopasowuje pojedynczą wielką literę

3

[a-zA-Z]

Dopasowuje pojedynczą literę

4

[0-9]

Dopasowuje pojedynczą liczbę

5

[a-zA-Z0-9]

Dopasowuje pojedynczą literę lub cyfrę

Słowa kluczowe klas znaków

Niektóre specjalne słowa kluczowe są powszechnie dostępne dla regexps, zwłaszcza narzędzia GNU, które wykorzystują regexps. Są one bardzo przydatne w wyrażeniach regularnych sed, ponieważ upraszczają rzeczy i zwiększają czytelność.

Na przykład postacie a through z i postacie A through Z, stanowią jedną taką klasę znaków, która ma słowo kluczowe [[:alpha:]]

Używając słowa kluczowego klasy znaków alfabetu, to polecenie wyświetla tylko te wiersze w /etc/syslog.conf plik zaczynający się od litery alfabetu -

$ cat /etc/syslog.conf | sed -n '/^[[:alpha:]]/p'
authpriv.*                         /var/log/secure
mail.*                             -/var/log/maillog
cron.*                             /var/log/cron
uucp,news.crit                     /var/log/spooler
local7.*                           /var/log/boot.log

Poniższa tabela zawiera pełną listę dostępnych słów kluczowych klas znaków w GNU sed.

Sr.No. Klasa postaci i opis
1

[[:alnum:]]

Alfanumeryczne [az AZ 0–9]

2

[[:alpha:]]

Alfabetycznie [az AZ]

3

[[:blank:]]

Puste znaki (spacje lub tabulatory)

4

[[:cntrl:]]

Znaki sterujące

5

[[:digit:]]

Liczby [0–9]

6

[[:graph:]]

Wszelkie widoczne znaki (z wyłączeniem białych znaków)

7

[[:lower:]]

Małe litery [az]

8

[[:print:]]

Znaki do druku (znaki inne niż sterujące)

9

[[:punct:]]

Znaki interpunkcyjne

10

[[:space:]]

Biała przestrzeń

11

[[:upper:]]

Wielkie litery [AZ]

12

[[:xdigit:]]

Cyfry szesnastkowe [0–9 af AF]

Aampersand Referencing

Plik sed metacharacter &reprezentuje zawartość wzorca, który został dopasowany. Załóżmy na przykład, że masz plik o nazwiephone.txt pełne numerów telefonów, na przykład następujące -

5555551212
5555551213
5555551214
6665551215
6665551216
7775551217

Chcesz, aby area code(pierwsze trzy cyfry) w nawiasach, aby ułatwić czytanie. Aby to zrobić, możesz użyć znaku zastępczego ampersand -

$ sed -e 's/^[[:digit:]][[:digit:]][[:digit:]]/(&)/g' phone.txt
(555)5551212
(555)5551213
(555)5551214
(666)5551215

(666)5551216
(777)5551217

Tutaj w części wzoru dopasowujesz pierwsze 3 cyfry, a następnie używasz & zastępujesz te 3 cyfry otoczeniem parentheses.

Używanie wielu poleceń sed

Możesz użyć wielu poleceń seda w jednym poleceniu sed w następujący sposób -

$ sed -e 'command1' -e 'command2' ... -e 'commandN' files

Tutaj command1 przez commandNsą poleceniami seda typu omówionego wcześniej. Te polecenia są stosowane do każdej linii na liście plików podanej przez pliki.

Korzystając z tego samego mechanizmu, możemy zapisać powyższy przykład numeru telefonu w następujący sposób -

$ sed -e 's/^[[:digit:]]\{3\}/(&)/g'  \ 
   -e 's/)[[:digit:]]\{3\}/&-/g' phone.txt 
(555)555-1212 
(555)555-1213 
(555)555-1214 
(666)555-1215 
(666)555-1216 
(777)555-1217

Note - W powyższym przykładzie zamiast powtarzania słowa kluczowego klasy znaków [[:digit:]] trzy razy zastąpiliśmy go \{3\}, co oznacza, że ​​poprzednie wyrażenie regularne jest dopasowywane trzykrotnie. Użyliśmy również\ aby dać podział wiersza i to musi zostać usunięte przed wykonaniem polecenia.

Wstecz Referencje

Plik ampersand metacharacterjest przydatna, ale jeszcze bardziej przydatna jest możliwość definiowania określonych regionów w wyrażeniach regularnych. Te specjalne regiony mogą służyć jako odniesienie w ciągach zastępczych. Definiując określone części wyrażenia regularnego, można następnie odwołać się do tych części za pomocą specjalnego znaku odniesienia.

Do zrobienia back references, musisz najpierw zdefiniować region, a następnie odwołać się do tego regionu. Aby zdefiniować region, wstawbackslashed parentheseswokół każdego regionu zainteresowania. Następnie odwołuje się do pierwszego regionu otoczonego odwrotnymi ukośnikami\1, drugi region wg \2, i tak dalej.

Zarozumiały phone.txt ma następujący tekst -

(555)555-1212
(555)555-1213
(555)555-1214
(666)555-1215
(666)555-1216
(777)555-1217

Wypróbuj następujące polecenie -

$ cat phone.txt | sed 's/\(.*)\)\(.*-\)\(.*$\)/Area \ 
   code: \1 Second: \2 Third: \3/' 
Area code: (555) Second: 555- Third: 1212 
Area code: (555) Second: 555- Third: 1213 
Area code: (555) Second: 555- Third: 1214 
Area code: (666) Second: 555- Third: 1215 
Area code: (666) Second: 555- Third: 1216 
Area code: (777) Second: 555- Third: 1217

Note - W powyższym przykładzie do każdego wyrażenia regularnego w nawiasie będzie się odwoływać \1, \2i tak dalej. Użyliśmy\aby zrobić przerwanie linii tutaj. Należy to usunąć przed uruchomieniem polecenia.