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.