Advanced Bash Regex z przykładami

Advanced Bash Regex z przykładami

Korzystając z mocy wyrażeń regularnych, można przeanalizować i przekształcić dokumenty i struny na podstawie tekstu. Ten artykuł jest przeznaczony dla zaawansowanych użytkowników, którzy już znają podstawowe wyrażenia regularne w Bash. Wprowadzenie do wyrażeń regularnych Bash można znaleźć w naszych wyrażeniach regularnych Bash dla początkujących z przykładami artykułu. Kolejnym artykułem, który możesz znaleźć interesujący, jest wyrażenia regularne w Pythonie.

gotowy żeby zacząć? Zanurz się i naucz się używać regularnej regexps jak profesjonalista!

W tym samouczku się nauczysz:

  • Jak uniknąć różnic w systemie operacyjnym od wpływu na wyrażenia regularne
  • Jak uniknąć używania zbyt generycznych stutów wyszukiwania wyrażeń regularnych, takich jak .*
  • Jak zastosować lub nie stosować, rozszerzoną składnię wyrażenia regularnej
  • Zaawansowane przykłady użytkowania złożonych wyrażeń regularnych w BASH
Advanced Bash Regex z przykładami

Zastosowane wymagania i konwencje oprogramowania

Wymagania oprogramowania i konwencje linii poleceń Linux
Kategoria Wymagania, konwencje lub wersja oprogramowania
System Niezależny od rozkładu Linuksa
Oprogramowanie Wiersz poleceń Bash, system oparty na Linuksie
Inny Narzędzie SED jest używane jako przykładowe narzędzie do stosowania wyrażeń regularnych
Konwencje # - Wymaga, aby podane Linux -commands były wykonywane z uprawnieniami root bezpośrednio jako użytkownik root lub za pomocą sudo Komenda
$-wymaga wykonania Linux-commands jako zwykłego niewidzianego użytkownika

Przykład 1: kieruje się przy użyciu rozszerzonych wyrażeń regularnych

W tym samouczku będziemy używać SED jako naszego głównego silnika przetwarzania wyrażeń regularnych. Wszelkie podane przykłady mogą być zwykle przeniesione bezpośrednio do innych silników, takich jak silniki ekspresji regularnej zawarte w GREP, AWK itp.

Jedną rzeczą, o której należy zawsze pamiętać podczas pracy z wyrażeniami regularnymi, jest to, że niektóre silniki od regularności (takie jak ten w SED) wspierają zarówno regularną, jak i rozszerzoną składnię wyrażenia regularnego. Na przykład SED pozwoli ci użyć -mi opcja (opcja skrótów dla --Przedłużanie regularności), umożliwiając użycie rozszerzonych wyrażeń regularnych w skrypcie SED.

Praktycznie powoduje to niewielkie różnice w idiomach składniowych wyrażeń regularnych podczas pisania skryptów wyrażenia regularnego. Spójrzmy na przykład:

$ echo „próbka” | sed 's | [a-e] \+| _ | g' s_mpl_ $ echo 'próbka' | sed 's | [a-e]+| _ | g' próbka $ echo 'próbka+' | sed 's | [a-e]+| _ | g' Sampl_ $ echo 'próbka' | sed -e 's | [a -e]+| _ | g' s_mpl_ 


Jak widać, w naszym pierwszym przykładzie użyliśmy \+ Aby zakwalifikować zakres A-C (zastąpiony globalnie z powodu G kwalifikator) jako wymagający jedno lub więcej zdarzeń. Zauważ, że w szczególności składnia jest \+. Jednak kiedy to zmieniliśmy \+ Do +, Polecenie dało zupełnie inne wyjście. To dlatego, że + nie jest interpretowany jako znak standardowy plus, a nie jako polecenie Regex.

Następnie udowodniło to trzecie polecenie, w którym dosłowne +, tak dobrze jak mi Przed nim został uchwycony przez wyrażenie regularne [a-e]+, i przekształcił się w _.

Patrząc wstecz, że pierwsze polecenie możemy teraz zobaczyć, jak \+ interpretowano jako nie litrarną ekspresję regularną +, do przetworzenia przez SED.

Wreszcie, w ostatnim poleceniu informujemy SED, że specjalnie chcemy użyć rozszerzonej składni za pomocą -mi Rozszerzona opcja składni do SED. Zauważ, że termin ten rozszerzony daje nam wskazówkę, co dzieje się w tle; Składnia wyrażeń regularnych jest rozszerzony Aby włączyć różne polecenia Regex, jak w tym przypadku +.

Kiedyś -mi jest używany, mimo że nadal używamy + i nie \+, sed poprawnie interpretuje + jako instrukcja wyrażania wyrażeń regularnych.

Kiedy piszesz wiele wyrażeń regularnych, te niewielkie różnice w wyrażaniu myśli w wyrażenia regularne zanikają w tle, a będziesz pamiętać najważniejsze.

Podkreśla to również potrzebę intensywnego testowania wyrażeń regularnych, biorąc pod uwagę różne możliwe dane wejściowe, nawet te, których się nie spodziewasz.

Przykład 2: Modyfikacja ciągów ciężkich

W tym przykładzie i kolejnych przygotowaliśmy plik tekstowy. Jeśli chcesz ćwiczyć, możesz użyć następujących poleceń, aby utworzyć ten plik dla siebie:

$ echo 'AbcDefghijklmnopqrstuvwxyz ABCDEFG 0123456789'> TEST1 $ CAT TEST1 ABCDEFSHIJKLMNOPQRSTUVWXYZ ABCDEFG 0123456789 

Spójrzmy teraz na nasz pierwszy przykład modyfikacji ciągów: Chcielibyśmy drugą kolumnę (ABCDEFG)ABCDEFGHIJKLMNOPQRSTU VWXYZ).

Na początek podejmujemy tę fikcyjną próbę:

$ CAT TEST1 ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFG 0123456789 $ CAT TEST1 | sed -e 's | ([a -o]+).*([A-Z]+) | \ 2 \ 1 | ' G ABCDEFGHIJKLMNO 0123456789 

Czy rozumiesz ten wyrażenie regularne? Jeśli tak, jesteś już bardzo zaawansowanym pisarzem wyrażeń regularnych i możesz zdecydować się przejść do następujących przykładów, przeglądając je, aby sprawdzić, czy jesteś w stanie je szybko zrozumieć, czy potrzebujesz trochę pomocy.

To, co tu robimy kot (wyświetlacz) Nasz plik test1 i paruj go z rozszerzonym wyrażeniem regularnym (dzięki -mi opcja) za pomocą SED. Moglibyśmy napisać to wyrażenie regularne, używając nieefektywnego wyrażenia regularnego (w SED) w następujący sposób;

$ CAT TEST1 | sed 's | \ ([a-o] \+\).*\ ([A-z] \+\) | \ 2 \ 1 | ' G ABCDEFGHIJKLMNO 0123456789 

Co jest dokładnie takie samo, z wyjątkiem tego, że dodaliśmy \ postać przed każdym (, ) I + Postać, wskazując SED, że chcemy, aby były analizowane jako kod wyrażenia regularnego, a nie jako zwykłe znaki. Spójrzmy teraz na sam wyrażenie regularne.

Skorzystajmy z tego rozszerzonego formatu wyrażenia regularnego, ponieważ łatwiej jest analizować wizualnie.

S | ([a-o]+).*([A-Z]+) | \ 2 \ 1 | 

Tutaj używamy polecenia zastępczego SED (S Na początku polecenia), a następnie wyszukiwanie (pierwszy |… | część) i wymień (drugi |… | część) Sekcja.

W sekcji wyszukiwania mamy dwa grupy selekcyjne, każdy otoczony i ograniczony przez ( I ), mianowicie ([A-O]+) I ([A-Z]+). Te grupy selekcyjne, w kolejności, które są podane, będą szukać podczas wyszukiwania strun. Zauważ, że pomiędzy grupą selekcyjną mamy .* Wyrażenie regularne, co zasadniczo oznacza dowolny znak, 0 lub więcej razy. To będzie pasowało pomiędzy ABCDEFGHIJKLMNOPQRSTU VWXYZ I ABCDEFG w pliku wejściowym i potencjalnie więcej.

W naszej pierwszej grupie wyszukiwania szukamy co najmniej jednego wystąpienia A-O a następnie jakakolwiek inna liczba wystąpień A-O, wskazane przez + kwalifikator. W drugiej grupie wyszukiwania szukamy wielkich liter między A I Z, I to znowu jeden lub więcej razy w sekwencji.

Wreszcie w naszej części zastąpienia sed Polecenie wyrażenia regularnego, będziemy Oddzwonić/wycofaj tekst wybrany przez te grupy wyszukiwania i wstaw je jako ciągami zastępcze. Zauważ, że zamówienie jest odwracane; najpierw wyjść tekst dopasowany przez drugą grupę selekcji (poprzez użycie \ 2 wskazując drugą grupę selekcji), a następnie tekst dopasowany przez pierwszą grupę selekcyjną (\ 1).

Chociaż może się to wydawać łatwe, wynik pod ręką (G ABCDEFGHIJKLMNO 0123456789) nie może być natychmiast jasne. Jak się zgubiliśmy ALFABET Na przykład? Straciliśmy też pqrstuvwxyz - czy zauważyłeś?



To, co się stało; Nasza pierwsza grupa selekcyjna uchwyciła tekst ABCDEFGHIJKLMNO. Następnie, biorąc pod uwagę .* (dowolny znak, 0 lub więcej razy) Wszystkie postacie zostały dopasowane - i to ważne; W maksymalnym zakresie - dopóki nie znajdziemy następnego odpowiedniego dopasowanego wyrażenia regularnego, jeśli w ogóle. W końcu dopasowaliśmy dowolny list z A-Z Zakres i to jeszcze raz.

Zaczynasz rozumieć, dlaczego straciliśmy ALFABET I pqrstuvwxyz? Chociaż nie jest to oczywiste, .* ciągle pasował do postaci do ostatni A-Z został dopasowany, co będzie G w ABCDEFG strunowy.

Mimo że określiliśmy jeden lub więcej (poprzez użycie +) Znaki, które należy dopasować, to szczególne wyrażenie regularne zostało poprawnie zinterpretowane przez SED od lewej do prawej, a SED zatrzymał się tylko z dopasowaniem dowolnej postaci (.*) Kiedy nie może już spełnić założenia, że ​​będzie przynajmniej jeden duże litery A-Z nadchodząca postać.

Razem, PQRSTUVWXYZ ABCDEF został zastąpiony przez .* Zamiast tylko przestrzeni, jak można by przeczytać to wyrażenie regularne w bardziej naturalnym, ale nieprawidłowym czytaniu. A ponieważ nie rejestrujemy wszystkiego, co zostało wybrane .*, Ten wybór został po prostu upuszczony z wyjścia.

Należy również zauważyć, że wszelkie części nie dopasowane przez sekcję wyszukiwania są po prostu kopiowane do wyjścia: sed będzie działać tylko na niezależnie od wyrażenia regularnego (lub dopasowania tekstu).

Przykład 3: Wybór wszystkiego, co nie jest

Poprzedni przykład prowadzi nas również do kolejnej interesującej metody, którą prawdopodobnie użyjesz, jeśli regularnie piszesz wyrażenia regularne, a to wybiera tekst za pomocą dopasowywania Wszystko, co nie jest. Brzmi jak fajnie powiedzieć, ale nie jasne, co to znaczy? Spójrzmy na przykład:

$ CAT TEST1 ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFG 0123456789 $ CAT TEST1 | sed -e 's | [^]*| _ |' ' _ ABCDEFG 0123456789 

Proste wyrażenia regularne, ale bardzo potężne. Tutaj, zamiast używać .* w jakimś kształcie lub sposób, którego użyliśmy [^]*. Zamiast mówić (przez .*) Dopasuj dowolny znak, 0 lub więcej razy, Teraz stwierdzamy Dopasuj dowolny znak bez przestrzeni, 0 lub więcej razy.

Chociaż wygląda to stosunkowo łatwo, wkrótce zdasz sobie sprawę z siły pisania wyrażeń regularnych w ten sposób. Pomyśl na przykład o naszym ostatnim przykładzie, w którym nagle mamy dużą część tekstu dopasowanego w nieco nieoczekiwany sposób. Można tego uniknąć, nieco zmieniając nasz wyrażenie regularne z poprzedniego przykładu, w następujący sposób:

$ CAT TEST1 | sed -e 's | ([a-o]+) [^a]+([a-z]+) | \ 2 \ 1 |' ABCDEFG ABCDEFGHIJKLMNO 0123456789 

Jeszcze nie idealne, ale już lepiej; Przynajmniej udało nam się zachować ALFABET część. Wszystko, co zrobiliśmy, to zmiana .* Do [^A]+. Innymi słowy, szukaj postaci, przynajmniej jednego, z wyjątkiem A. Raz A znajduje się, że część analizy analizy wyrażenia zatrzymuje się. A sama nie będzie również uwzględniona w meczu.

Przykład 4: Wracanie do naszego pierwotnego wymogu

Czy możemy zrobić lepiej i rzeczywiście poprawnie zamienić pierwszą i drugą kolumny?

Tak, ale nie poprzez zachowanie wyrażenia regularnego jako is. W końcu robi to, o co prosiliśmy; Dopasuj wszystkie postacie z A-O Korzystanie z pierwszej grupy wyszukiwania (i wyjścia później na końcu łańcucha), a następnie wyrzucać Każda postać, dopóki SED nie osiągnie A. Moglibyśmy ostatecznie rozwiązać problem - pamiętaj, że chcieliśmy dopasować tylko przestrzeń - rozszerzając/zmieniając A-O Do A-Z, lub po prostu dodając inną grupę wyszukiwania i dosłownie dopasowując przestrzeń:

$ CAT TEST1 | sed -e 's | ([a-o]+) ([^]+) [] ([a-z]+) | \ 3 \ 1 \ 2 |' ABCDEFG ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 

Świetnie! Ale wyrażenie regularne wygląda teraz zbyt złożone. Dopasowaliśmy A-O jeden lub więcej razy w pierwszej grupie, a następnie dowolna postać nie przestrzeni (dopóki SED znajdzie przestrzeń lub koniec sznurka) w drugiej grupie, a następnie dosłowne miejsce i wreszcie A-Z jeden lub więcej razy.

Czy możemy to uprościć? Tak. I to powinno podkreślić, w jaki sposób można łatwo przepełnić skrypty wyrażenia regularnego.

$ CAT TEST1 | sed -e 's | ([^]+) ([^]+) | \ 2 \ 1 |' ' ABCDEFG ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 $ CAT TEST1 | awk 'drukuj 2 $ "" $ 1 "" $ 3' ABCDEFG ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 


Oba rozwiązania osiągają oryginalne wymagania, przy użyciu różnych narzędzi, znacznie uproszczonej regex dla polecenia SED i bez błędów, przynajmniej dla dostarczonych strun wejściowych. Czy to łatwo może się pomylić?

$ CAT TEST1 ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFG 0123456789 $ CAT TEST1 | sed -e 's | ([^]+) ([^]+) | \ 2 \ 1 |' ' ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 ABCDEFG 

Tak. Wszystko, co zrobiliśmy, to dodanie dodatkowego miejsca na wejściu, a przy użyciu tego samego wyrażenia regularnego nasze wyjście jest teraz całkowicie niepoprawne; Druga i trzecia kolumny zostały zamienione zamiast pięści dwa. Ponownie podświetlona jest potrzeba szczegółowego testowania wyrażeń regularnych i z różnorodnymi wejściami. Różnica w wyjściu wynosi po prostu dlatego, że wzór bez przestrzeni bez przestrzeni może być dopasowany tylko przez drugą część ciągu wejściowego z powodu podwójnej przestrzeni.

Przykład 5: LS Gotcha?

Czasami ustawienie poziomu systemu operacyjnego, na przykład przy użyciu wyjścia kolorów dla list katalogowych, czy nie (które można ustawić domyślnie!), spowoduje, że skrypty wiersza poleceń zachowują się nieregularnie. Chociaż w żadnym wypadku nie jest to bezpośrednia wina wyrażeń regularnych, jest to gotcha, którą można łatwo wpaść podczas korzystania z wyrażeń regularnych. Spójrzmy na przykład:

LS kolorystyczne daluty wyniki polecenia zawierające wyrażenia regularne
$ ls -d t* test1 test2 $ ls -d t* 2 | sed | 2 | 1 | '' test1 $ ls -d t*2 | sed | 2 | 1 | '' |. Xargs LS LS: Nie można uzyskać dostępu ”

W tym przykładzie mamy katalog (test2) i plik (test1), oba są wymienione przez oryginał ls -d Komenda. Następnie wyszukiwamy wszystkie pliki z wzorem nazwy plików t*2, i usuń 2 z nazwy pliku za pomocą sed. Rezultatem jest tekst test. Wygląda na to, że możemy użyć tego wyjścia test natychmiast po inne polecenie i wysłaliśmy je przez Xargs do LS polecenie, oczekując LS Polecenie do wyświetlenia pliku test1.

Jednak tak się nie dzieje, a zamiast tego otrzymujemy bardzo złożone dane wyjściowe. Powód jest prosty: oryginalny katalog został wymieniony w ciemnoniebieskim kolorze, a ten kolor jest zdefiniowany jako seria kodów kolorów. Kiedy zobaczysz to po raz pierwszy, dane wyjściowe jest trudne do zrozumienia. Rozwiązanie jest jednak proste;

$ ls -d -color = nigdy t*2 | sed | 2 | 1 | '' |. XARGS LS TEST1 

Zrobiliśmy LS Wyjście polecenia Listing bez użycia żadnego koloru. To całkowicie rozwiązuje problem i pokazuje, jak możemy trzymać się w naszych umysłach potrzebę unikania małych, ale znaczących, specyficznych dla systemu Os ustawień i gotchas, które mogą przełamać naszą pracę wyrażenia regularnego, gdy jest wykonywane w różnych środowiskach, włączone, włączone inny sprzęt lub w różnych systemach operacyjnych.

Gotowy do dalszego odkrycia samodzielnie? Spójrzmy na niektóre z najczęstszych wyrażeń regularnych dostępnych w Bash:

Wyrażenie Opis
. Każda postać, z wyjątkiem nowości
[a-c] Jeden znak wybranego zakresu, w tym przypadku A, B, C
[A-Z] Jeden znak wybranego zakresu, w tym przypadku A-Z
[0-9af-z] Jeden znak wybranego zakresu, w tym przypadku 0-9, a i f-z
[^A-za-z] Jedna postać poza wybranym zakresem, w tym przypadku na przykład „1” kwalifikowałby się
\* Lub * Dowolna liczba meczów (0 lub więcej). Użyj * podczas korzystania z wyrażeń regularnych, w których rozszerzone wyrażenia nie są włączone (patrz pierwszy przykład powyżej)
\+ lub + 1 lub więcej meczów. Komentarz idem jako *
\ (\) Grupa przechwytywania. Po raz pierwszy jest to używane, liczba grupy to 1 itp.
^ Początek ciągu
$ Koniec ciągu
\D Jedna cyfra
\D Jeden nie cyfr
\S Jedna biała przestrzeń
\S Jedna nie biała przestrzeń
a | d Jedna postać z nich (alternatywa dla używania []), „a” lub „d”
\ Ucieka z znakami specjalnymi lub wskazuje, że chcemy użyć wyrażenia regularnego, w którym rozszerzone wyrażenia nie są włączone (patrz pierwszy przykład powyżej)
\B Postać backspace
\N Nowa postać
\R Znak powrotu powozu
\T Znak tablicy

Wniosek

W tym samouczku wyglądaliśmy dogłębnie na wyrażenia regularne Bash. Odkryliśmy potrzebę testowania naszych wyrażeń regularnych, z różnorodnymi wejściami. Widzieliśmy również, jak małe różnice systemu operacyjnego, takie jak używanie koloru LS Polecenia czy nie, mogą prowadzić do bardzo nieoczekiwanych wyników. Nauczyliśmy się potrzeby unikania zbyt generycznych wzorów wyrażeń regularnych i sposobu stosowania rozszerzonych wyrażeń regularnych.

Ciesz się pisaniem zaawansowanych wyrażeń regularnych i zostaw nam komentarz poniżej z najfajniejszymi przykładami!

Powiązane samouczki Linux:

  • Bash Regexps dla początkujących z przykładami
  • Wyrażenia regularne Pythona z przykładami
  • Manipulacja Big Data dla zabawy i zysku Część 3
  • Wprowadzenie do automatyzacji, narzędzi i technik Linuksa
  • Rzeczy do zainstalowania na Ubuntu 20.04
  • Manipulacja Big Data dla zabawy i zysku Część 2
  • Big Data Manipulacja dla zabawy i zysku Część 1
  • Mastering Bash Script Loops
  • Mint 20: Lepsze niż Ubuntu i Microsoft Windows?
  • Rzeczy do zrobienia po zainstalowaniu Ubuntu 20.04 Focal Fossa Linux