Egrep primjeri regularnih izraza. Pet primjera korištenja grep

U današnjem članku želim se dotaknuti tako velike teme kao što je Regularni izrazi... Mislim da svi znaju da je tema regularnih izraza (kako se u slengu nazivaju regularni izrazi) ogromna u obimu jednog posta.

Za početak, postoji nekoliko vrsta regularnih izraza:

1. Tradicionalni regularni izrazi(oni su takođe osnovni, osnovni i osnovne regularne izraze(BRE))

  • sintaksa za ove izraze je definirana kao zastarjela, ali je ipak još uvijek široko rasprostranjena i korištena od strane mnogih UNIX uslužnih programa
  • Osnovni regularni izrazi uključuju sljedeće metakaraktere (pogledajte njihova značenja u nastavku):
    • \ (\) - original za () (u proširenom)
    • \ (\) - original za () (u proširenom)
    • \n, gdje n- broj od 1 do 9
  • Karakteristike korištenja ovih metakaraktera:
    • Zvjezdica mora pratiti izraz koji odgovara jednom znaku. Primjer: *.
    • Izraz \( blok\) * treba smatrati nevažećim. U nekim slučajevima, odgovara nula ili više ponavljanja niza. blok... Kod drugih se podudara sa nizom blok* .
    • Unutar klase znakova, značenja posebnih znakova se općenito zanemaruju. Posebni slučajevi:
    • Da biste dodali znak ^ u skup, on ne smije biti prvi tamo.
    • Da biste dodali simbol - u skup, on mora biti postavljen prvi ili zadnji. Na primjer:
      • DNS obrazac imena, koji može uključivati ​​slova, brojeve, minus i tačku za razdvajanje: [-0-9a-zA-Z.];
      • bilo koji znak osim minusa i cifre: [^ -0-9].
    • Da biste dodali znak [ili] skupu, on se mora prvo postaviti tamo. Na primjer:
      • podudara se], [, a ili b.

2. Prošireni regularni izrazi(oni su prošireni regularni izrazi(ERE))

  • Sintaksa za ove izraze je ista kao i za glavne izraze, osim:
    • Uklonjena je upotreba obrnutih kosih crta za () i () metakaraktere.
    • Obratna kosa crta ispred metaznaka poništava njegovo posebno značenje.
    • Odbijeno teoretski nepravilan konstrukcija \ n .
    • Dodani metaznakovi +,? , | ...

3. Perl kompatibilni regularni izrazi(oni su Perl-kompatibilni regularni izrazi(PCRE))

  • imaju bogatiju i istovremeno predvidljivu sintaksu od čak POSIX ERE, stoga se često koristi u aplikacijama.

Regularni izrazi sastoji se odšablone, odnosno postaviti obrazac traži. Šablon se sastoji od pravila pretrage, koje se sastoje od karaktera i metakarakteri.

Pravila pretraživanja definisano sledećim operacije:

Nabrajanje |

Vertikalna traka (|) razdvaja važeće opcije, možemo reći - logičko ILI. Na primjer, "siva | siva" odgovara siva ili siva.

Grupisanje ili udruživanje ()

Okrugle zagrade koriste se za definiranje opsega i prioriteta operatora. Na primjer, "siva | siva" i "gr (a | e) y" su različiti obrasci, ali oba opisuju skup koji sadrži siva i siva.

Kvantifikacija ()? * +

Kvantifikator nakon što znak ili grupa određuje koliko puta prije može doći do izražaja.

opšti izraz, ponavljanja mogu biti od m do n uključujući.

opšti izraz, m ili više ponavljanja.

opšti izraz, ne više od n ponavljanja.

glatkon ponavljanja.

Upitnik znači 0 ili 1 puta, isto kao {0,1} ... Na primjer, "colou? R" odgovara i boja, i boja.

Star znači 0, 1 ili bilo koji broj jednom ( {0,} ). Na primjer, "go * gle" odgovara ggle, naočare, google i sl.

A plus znači najmanje 1 jednom ( {1,} ). Na primjer, "go + gle" odgovara naočare, google itd. (ali ne ggle).

Specifična sintaksa za ove regularne izraze ovisi o implementaciji. (odnosno u osnovne regularne izraze simboli ( i )- pobjegno sa obrnutom kosom crtom)

Metakarakteri, jednostavno rečeno, to su simboli koji ne odgovaraju njihovom pravom značenju, odnosno simbolu. (tačka) nije tačka, već bilo koji znak, itd. upoznajte se sa metaznacima i njihovim značenjima:

. odgovara jedan bilo kog karaktera
[nešto] U skladu sa bilo koji singl znak zatvoren u zagrade. U ovom slučaju: Znak "-" tumači se doslovno samo ako se nalazi odmah nakon otvaranja ili prije završne zagrade: ili [-abc]. Inače, označava raspon znakova. Na primjer, odgovara "a", "b" ili "c". odgovara malim slovima latinice. Ove oznake se mogu i kombinovati: odgovaraju a, b, c, q, r, s, t, u, v, w, x, y, z. Za podudaranje znakova "[" ili "]" dovoljno je da završna zagrada je bila prvi znak nakon početnog znaka: odgovara "]", "[", "a" ili "b". Ako je ispred vrijednosti u uglastim zagradama ^, tada se vrijednost izraza podudara jedan karakter među njima koje nisu u zagradama... Na primjer, [^ abc] odgovara bilo kojem znaku osim "a", "b" ili "c". [^ a-z] odgovara bilo kojem znaku osim latiničnim malim slovima.
^ Poklapa se s početkom teksta (ili početkom bilo kojeg reda ako je u načinu rada).
$ Odgovara kraju teksta (ili kraju bilo kojeg reda ako je umetnuti način).
\(\) ili () Deklariše "označeni podizraz" (grupisani izraz) koji se može koristiti kasnije (pogledajte sljedeći element: \ n). "Označeni podizraz" je takođe "blok". Za razliku od drugih operatora, ovaj (u tradicionalnoj sintaksi) zahtijeva obrnutu kosu crtu, u proširenom i Perl-u \ - nije potreban.
\n Gdje n- ovo je broj od 1 do 9; odgovara n th označeni podizraz (na primjer (abcd) \ 0, odnosno abcd znakovi su označeni nulom). Ova konstrukcija je teoretski nepravilan, nije prihvaćeno u proširenoj sintaksi regularnog izraza.
*
  • Star nakon što se izraz podudara sa jednim znakom nula ili više kopije ovog (prethodnog) izraza. Na primjer, "*" odgovara praznom nizu, "x", "y", "zx", "zyx", itd.
  • \n*, gdje n Je cifra od 1 do 9, odgovara nula ili više pojavljivanja za podudaranje n th označeni podizraz. Na primjer, "\ (a. \) C \ 1 *" odgovara "abcab" i "abcaba", ali ne i "abcac".

Izraz zatvoren u "\ (" i "\)" iza kojeg slijedi "*" treba se smatrati nevažećim. U nekim slučajevima, odgovara nula ili više pojavljivanja niza koji je zatvoren u zagradama. U drugim slučajevima, odgovara izrazu zatvorenom u zagradama, s obzirom na znak "*".

\{x,y\} Odgovara potonjem ( predstojeći) na blok koji se pojavi najmanje x i ne više y jednom. Na primjer, "a \ (3,5 \)" odgovara "aaa", "aaaa" ili "aaaaa". Za razliku od drugih operatora, ovaj (u tradicionalnoj sintaksi) zahtijeva obrnutu kosu crtu.
.* Označavanje bilo kojeg broja bilo kojeg karaktera između dva dijela regularnog izraza.

Metaznakovi nam pomažu da koristimo različite podudarnosti. Ali kako predstavljati metaznak sa regularnim karakterom, odnosno znakom [(uglata zagrada) vrijednošću uglaste zagrade? samo:

  • mora prethoditi ( štit) metaznak (. * + \? ()) obrnuta kosa crta. Na primjer \. ili \[

Da bi se pojednostavila definicija nekih skupova karaktera, oni su kombinovani u tzv. klase i kategorije likova. POSIX je standardizirao deklaraciju određenih klasa i kategorija simbola, kao što je prikazano u sljedećoj tabeli:

POSIX klasa slično oznaka
[: gornji:] velika slova
[: niže:] mala slova
[: alfa:] velika i mala slova
[: alnum:] brojevi, velika i mala slova
[: cifra:] brojevi
[: xdigit:] heksadecimalne cifre
[: punct:] [.,!?:…] znakovi interpunkcije
[: prazno:] [\ t] razmak i TAB
[: svemir:] [\ t \ n \ r \ f \ v] preskakanje znakova
[: cntrl:] kontrolni simboli
[: graf:] [^ \ t \ n \ r \ f \ v] ispis simbola
[: print:] [^ \ t \ n \ r \ f \ v] ispisati i preskočiti znakove

U regularnom izrazu postoji nešto poput:

Regex pohlepe

Pokušat ću to opisati što je moguće jasnije. Recimo da želimo pronaći sve HTML oznake u nekom tekstu. Nakon što smo lokalizirali zadatak, želimo pronaći vrijednosti zatvorene između< и >, zajedno sa ovim istim zagradama. Ali znamo da tagovi imaju različite dužine i same oznake, najmanje 50 komada.Da ih sve nabrojimo, njihovo zatvaranje u metaznakove je previše dugotrajan zadatak. Ali znamo da imamo izraz * (tačka zvjezdica) koji karakterizira bilo koji broj bilo kojeg karaktera u nizu. Koristeći ovaj izraz, pokušat ćemo pronaći u tekstu (

dakle, Kako kreirati RAID nivo 10/50 na LSI MegaRAID kontroleru (važi i za: Intel SRCU42x, Intel SRCS16):

) sve vrijednosti između< и >... Kao rezultat, SVE linije će odgovarati ovom izrazu. zašto, zato što je regex POHLEPAN i pokušava uhvatiti SVAKI broj znakova između< и >, odnosno cijela linija, počevši < p> Dakle... i kraj ...> pripadaće ovom pravilu!

Nadamo se da je ovo primjer šta je pohlepa. Da biste se riješili ove pohlepe, možete ići sljedećim putem:

  • uzeti u obzir simbole, ne odgovara željenom uzorku (na primjer:<[^>] *> za gornji slučaj)
  • riješite se pohlepe dodavanjem definicije ne-pohlepnog kvantifikatora:
    • *? - "nije pohlepan" ("lijenji") ekvivalent *
    • +? - "nije pohlepan" ("lijenji") ekvivalent +
    • (n,)? - "nije pohlepan" ("lijenji") ekvivalentno (n,)
    • *? - "nije pohlepan" ("lijenji") ekvivalent. *

Želim dopuniti sve navedeno sa proširenom sintaksom regularnog izraza:

POSIX regularni izrazi su slični tradicionalnoj Unix sintaksi, ali sa dodatkom nekih metakaraktera:

A plus ukazuje na to prethodni simbol ili grupa može se ponoviti jedan ili više puta... Za razliku od zvjezdice, potrebno je najmanje jedno ponavljanje.

Upitnik radi prethodni karakter ili grupa opciono. Drugim riječima, u odgovarajućem redu, it može biti odsutan ili prisutan glatko jedan jednom.

Vertikalna traka odvaja alternativne regularne izraze. Jedan simbol definira dvije alternative, ali ih može biti više, dovoljno je koristiti više okomitih traka. Zapamtite da ovaj operator koristi što je više moguće izraza. Iz tog razloga, alternativni operator se najčešće koristi unutar zagrada.

Upotreba obrnutih kosih crta je također uklonjena: \ (... \) postaje (...) i \ (... \) postaje (...).

Na kraju posta, evo nekoliko primjera korištenja redovnog izraza:

$ cat text1 1 jabuka 2 kruška 3 banana $ grep p text1 1 jabuka 2 kruška $ grep grašak text1 2 kruška $ grep "p *" text1 1 jabuka 2 kruška 3 banana $ grep "pp *" text1 1 jabuka 2 kruška $ grep " x "text1 $ grep" x * "text1 1 jabuka 2 kruška 3 banana $ mačka text1 | grep "l \ | n" 1 jabuka 3 banana $ echo -e "pronađi \ n * ovdje" | grep "\ *" * ovdje $ grep "pp \ +" text1 # redovi koji sadrže jedno p i 1 ili više p 1 jabuka $ grep "pl \? e" text1 1 jabuka 2 kruška $ grep "pl \? e" text1 # pe sa mogućim znakom l 1 jabuka 2 kruška $ grep "p. * r" text1 # p, u redovima koji sadrže r 2 kruška $ grep "a .." text1 # redovi sa a nakon kojih slijede najmanje 2 znaka 1 jabuka 3 banana $ grep "\ (an \) \ +" text1 # Traži više ponavljanja an 3 banana $ grep "an \ (an \) \ +" text1 # traži 2 ponavljanja 3 banana $ grep "" text1 # traži linije sa 3 ili p 1 jabuka 2 kruška 3 banana $ echo -e "pronađi \ n * ovdje \ nnegdje." | grep "[. *]" * ovdje negdje. $ # Traži znakove od 3 do 7 $ echo -e "123 \ n456 \ n789 \ n0" | grep "" 123 456 789 $ # Tražimo cifru, bez slova n i r do kraja reda $ grep "[[: cifra:]] [^ nr] * $" text1 1 jabuka $ sed -e "/ \ (a . * a \) \ | \ (p. * p \) / s / a / A / g "text1 # zamijeni a sa A u svim redovima gdje a dolazi iza a ili p dolazi poslije p 1 jabuka 2 kruška 3 bAnAnA $ sed -e "/ ^ [^ lmnXYZ] * $ / s / uho / svaki / g" text1 # zamijeni uho sa svakim na linijama koje ne počinju sa lmnXYZ 1 jabuka 2 breskva 3 banana $ echo "Prvo . Fraza. Ovo je rečenica." | \ # Zamijenite zadnju riječ u rečenici sa POSLEDNJI SVIJET. > sed -e "s / [^] * \ ./ POSLEDNJA RIJEČ./g" Prvo. POSLJEDNJA RIJEČ. Ovo je POSLJEDNJA RIJEČ.

Pozadina i izvor: ne razumeju svi koji moraju da koriste regularne izraze u potpunosti kako oni rade i kako da ih kreiraju. I ja sam pripadao ovoj grupi - tražio sam primjere regularnih izraza koji odgovaraju mojim zadacima, pokušavao sam ih ispraviti po potrebi. Za mene se sve radikalno promijenilo nakon čitanja knjige. Linux komandna linija (drugo internetsko izdanje) autor William E. Shotts, Jr. U njemu su principi rada regularnih izraza izloženi tako jasno da sam nakon čitanja naučio da ih razumijem, kreiram regularne izraze bilo koje složenosti, a sada ih koristim kad god je potrebno. Ovaj materijal je prijevod dijela poglavlja posvećenog regularnim izrazima. Ovaj materijal je namijenjen apsolutnim početnicima koji uopće ne razumiju kako funkcioniraju regularni izrazi, ali imaju neku ideju o tome kako funkcioniraju. Nadam se da će vam ovaj članak pomoći da napravite isti napredak koji je pomogao i meni. Ako vam materijal ovdje nije ništa novo, isprobajte članak Regularni izrazi i naredbu grep za više detalja o grep opcijama i dodatnim primjerima.

Kako se koriste regularni izrazi

Tekstualni podaci igraju važnu ulogu u svim sistemima sličnim Unixu kao što je Linux. Između ostalog, tekst je izlaz konzolnih programa, konfiguracijskih datoteka, izvještaja itd. Regularni izrazi su (možda) jedan od najtežih koncepata za rad s tekstom, jer uključuju visok nivo apstrakcije. Ali vrijeme provedeno u proučavanju će se isplatiti s kamatama. Poznavanje upotrebe regularnih izraza može vam pomoći da radite nevjerovatne stvari, iako njihova puna vrijednost možda neće biti odmah vidljiva.

Ovaj članak će vas provesti kroz upotrebu regularnih izraza u kombinaciji s naredbom grep... Ali njihova primjena nije ograničena samo na ovo: regularne izraze podržavaju druge Linux komande, mnogi programski jezici, koriste se u konfiguraciji (na primjer, u postavkama mod_rewrite pravila u Apacheu), a također i neki GUI programi vam omogućavaju postaviti pravila za pretraživanje / kopiranje / brisanje iz podrške za regularne izraze. Čak iu popularnom uredskom programu Microsoft Word, možete koristiti regularne izraze i zamjenske znakove za pronalaženje i zamjenu teksta.

Šta su regularni izrazi?

Jednostavno rečeno, regularni izraz je stenografija, simbolička notacija za obrazac koji se traži u tekstu. Regularni izrazi su podržani od strane mnogih alata komandne linije i većine programskih jezika i koriste se da vam pomognu u rješavanju problema s manipulacijom tekstom. Međutim (kao da nam njihova složenost nije dovoljna), nisu svi regularni izrazi isti. Oni se neznatno razlikuju od alata do alata i od programskog jezika do jezika. Za našu diskusiju, ograničit ćemo se na regularne izraze opisane u POSIX standardu (koji će pokrivati ​​većinu alata komandne linije), za razliku od mnogih programskih jezika (najčešće Perl) koji koriste nešto veće i bogatije skupove notacija.

grep

Glavni program koji ćemo koristiti za regularne izraze je naš stari prijatelj,. Naziv "grep" zapravo dolazi od fraze "global regular expression print", tako da možemo vidjeti da grep ima neke veze sa regularnim izrazima. U suštini, grep pretražuje tekstualne datoteke za tekst koji odgovara navedenom redovnom izrazu i ispisuje bilo koji red koji odgovara navedenom nizu na standardni izlaz.

grep može tražiti tekst primljen standardnim unosom, na primjer:

Ls / usr / bin | grep zip

Ova komanda će ispisati datoteke u /usr / bin direktoriju čija imena sadrže podniz "zip".

Grep može tražiti tekst u datotekama.

Opća sintaksa upotrebe:

Grep [opcije] regex [fajl ...]

  • regex je regularni izraz.
  • [fajl…]- jedan ili više fajlova u kojima će se izvršiti pretraga regularnog izraza.

[opcije] i [datoteka ...] možda nedostaju.

Lista najčešće korištenih grep opcija:

Opcija Opis
-i Zanemari velika i mala slova. Ne pravite razliku između velikih i malih znakova. Može se podesiti i sa opcijom --ignore-case.
-v Invert match. Obično grep ispisuje linije koje sadrže podudaranje. Ova opcija uzrokuje da grep ispisuje svaki red koji se ne podudara. Također možete koristiti --invert-match.
-c Ispišite broj podudaranja (ili nepodudaranja ako je navedena opcija -v) umjesto samih nizova. Može se specificirati i sa opcijom --count.
-l Umjesto samih linija, ispišite naziv svake datoteke koja sadrži podudaranje. Može se specificirati opcijom --fajlovi-sa-podudarnostima.
-L Kao opcija -l ali ispisuje samo imena datoteka koja ne sadrže podudaranja. Drugo ime opcije --fajlovi-bez podudaranja.
-n Dodaje broj reda unutar datoteke na početak svakog podudarnog reda. Drugo ime opcije --broj-line.
-h Za pretraživanje više datoteka, potisnite izlaz imena datoteke. Također možete odrediti opciju --bez imena datoteke.

Da bismo potpunije istražili grep, napravimo neke tekstualne datoteke za pretraživanje:

Ls / bin> dirlist-bin.txt ls / usr / bin> dirlist-usr-bin.txt ls / sbin> dirlist-sbin.txt ls / usr / sbin> dirlist-usr-sbin.txt ls dirlist * .txt dirlist -bin.txt dirlist-sbin.txt dirlist-usr-bin.txt dirlist-usr-sbin.txt

Možemo izvršiti jednostavnu pretragu kroz našu listu datoteka poput ove:

Grep bzip dirlist * .txt dirlist-bin.txt: bzip2 dirlist-bin.txt: bzip2recover

Ovaj primjer grep pretražuje sve navedene datoteke za bzip string i pronalazi dva podudaranja, oba u datoteci dirlist-bin.txt. Ako nas zanima samo lista datoteka koje sadrže podudaranja, a ne i same odgovarajuće linije, možemo odrediti opciju -l:

Grep -l bzip dirlist * .txt dirlist-bin.txt

Suprotno tome, ako želimo samo vidjeti listu datoteka koje ne sadrže podudaranja, mogli bismo učiniti ovo:

Grep -L bzip dirlist * .txt dirlist-sbin.txt dirlist-usr-bin.txt dirlist-usr-sbin.txt

Ako nema izlaza, onda datoteke koje odgovaraju uvjetima nisu pronađene.

Metaznakovi i literali

Iako ovo možda ne izgleda očigledno, naše grep pretrage uvijek koriste regularne izraze, iako vrlo jednostavne. Regularni izraz "bzip" znači da će doći do podudaranja (tj. string će se smatrati prikladnim) samo ako red u datoteci sadrži najmanje četiri znaka i da se negdje u nizu nalaze znakovi "b", "z " , "I" i "p" su tim redoslijedom, bez drugih znakova između. Znakovi u "bzip" nizu su literali, tj. doslovni simboli kako odgovaraju sami sebi. Pored literala, regularni izrazi takođe mogu uključivati metakarakteri koji se koriste za specificiranje složenijih podudaranja. Metaznakovi regularnog izraza sastoje se od sljedećeg:

^ $ . { } - ? * + () | \

Svi ostali znakovi se smatraju literalima. Obrnuta kosa crta može imati različita značenja. Koristi se u nekoliko slučajeva za kreiranje meta sekvence i također omogućava da se metaznakovi izbjegnu i tretiraju kao literali, a ne kao metaznaci.

Bilješka: kao što vidimo, mnogi metaznakovi regularnog izraza su takođe znakovi koji imaju značenje ljuske (izvršavaju proširenje). Kada specificirate regularni izraz koji sadrži metakaraktere komandne linije, imperativ je da ga stavite u navodnike, inače će ih školjka drugačije interpretirati i prekinuti vašu naredbu.

Bilo koji lik

Prvi metalik s kojim započinjemo naše upoznavanje je simbol tačkešto znači "bilo koji karakter". Ako ga uključimo u regex, onda će odgovarati bilo kojem znaku za tu poziciju znaka. primjer:

Grep -h ".zip" dirlist * .txt bunzip2 bzip2 bzip2recover gunzip gzip funzip gpg-zip mzip p7zip preunzip prezip prezip-bin raspakirajte unzipsfx

Potražili smo bilo koju liniju u našim datotekama koja odgovara regularnom izrazu ".zip". U dobijenim rezultatima treba istaći nekoliko zanimljivosti. Imajte na umu da zip program nije pronađen. To je zato što je uključivanje metaznaka tačke u naš regularni izraz povećalo dužinu potrebnu za podudaranje na četiri znaka, a pošto naziv "zip" sadrži samo tri, ono se ne podudara. Takođe, ako bi bilo koja od datoteka na našim listama sadržavala ekstenziju datoteke .zip, oni bi se također smatrali važećim, jer znak tačke u ekstenziji datoteke također odgovara uslovu "bilo koji karakter".

Sidra

Znak za umetanje ( ^ ) i znak dolara ( $ ) se razmatraju u regularnim izrazima sidra... To znači da se podudaraju samo ako se regex nalazi na početku reda ( ^ ) ili na kraju reda ( $ ):

Grep -h "^ zip" dirlist * .txt zip zipcloak zipdetails zipgrep zipinfo zipnote zipsplit grep -h "zip $" dirlist * .txt gunzip gzip funzip gpg-zip mzip p7zip preunzip unzip prezip zip zip zip zip"

Ovde smo pregledali liste fajlova za "zip" red koji se nalazi na početku reda, na kraju reda, kao i u redu gde bi bio i na početku i na kraju (tj. cijeli red bi sadržavao samo "zip" ). Imajte na umu da regularni izraz " ^$ "(Početak i kraj između kojih nema ničega) će odgovarati praznim redovima.

Mala lirska digresija: pomoćnik za rješavanje križaljki

Čak i sa našim trenutno ograničenim znanjem o regularnim izrazima, možemo učiniti nešto korisno.

Ako ste ikada radili ukrštene reči, onda ste morali da rešavate probleme poput „kakva reč od pet slova, gde je treće slovo „j“, a poslednje slovo „r“, što znači...“. Ovo pitanje može izazvati razmišljanje. Jeste li znali da postoji rječnik na Linuxu? I jeste. Pogledajte u /usr / share / dict direktorij, tamo možete pronaći jedan ili više rječnika. Rječnici koji su tamo postavljeni su samo dugačke liste riječi, jedna po redu, raspoređene po abecednom redu. Na mom sistemu, datoteka rječnika sadrži 99.171 riječ. Da bismo potražili moguće odgovore na gornju ukrštenicu, možemo učiniti sljedeće:

Grep -i "^ .. j.r $" / usr / share / dict / američki-engleski glavni smjer

Koristeći ovaj regularni izraz, možemo pronaći sve riječi u našoj rječničkoj datoteci koje imaju pet slova, imaju "j" na trećoj poziciji i "r" na posljednjoj poziciji.

U primjeru je korištena datoteka rječnika engleskog jezika jer je po defaultu prisutna na sistemu. Nakon što ste prethodno preuzeli odgovarajući rečnik, možete vršiti slične pretrage reči na ćirilici ili iz bilo kojih drugih znakova.

Izrazi zagrada i klase znakova

Osim podudaranja bilo kojeg znaka na datoj poziciji u našem redovnom izrazu, također koristimo izrazi u uglastim zagradama, možemo upariti jedan znak iz specificiranog skupa znakova. Sa izrazima u uglastim zagradama, možemo odrediti skup znakova koji će odgovarati (uključujući znakove koji bi se inače tumačili kao metaznakovi). U ovom primjeru, koristeći skup od dva znaka:

Grep -h "zip" dirlist * .txt bzip2 bzip2recover gzip

naći ćemo sve linije koje sadrže nizove "bzip" ili "gzip".

Skup može sadržavati bilo koji broj znakova, a metaznakovi gube svoje posebno značenje kada se stave unutar uglastih zagrada. Međutim, postoje dva slučaja u kojima metaznakovi korišteni unutar uglastih zagrada imaju različita značenja. Prvi je karet ( ^ ), koji se koristi za označavanje negacije; druga je crtica ( - ), koji se koristi za specificiranje raspona znakova.

Negacija

Ako je prvi znak izraza u uglastim zagradama znak za ucrtavanje ( ^ ), tada se ostali znakovi prihvataju kao skup znakova koji ne bi trebao biti prisutan na datoj poziciji karaktera. Učinimo to modifikacijom našeg prethodnog primjera:

Grep -h "[^ bg] zip" dirlist * .txt bunzip2 gunzip funzip gpg-zip mzip p7zip preunzip prezip prezip-bin raspakirajte unzipsfx

Sa aktiviranom negacijom, dobili smo listu datoteka koje sadrže niz "zip" kojem prethodi bilo koji znak osim "b" ili "g". Imajte na umu da zip nije pronađen. Negirani skup znakova i dalje zahtijeva karakter na datoj poziciji, ali znak ne smije biti član invertovanog skupa znakova.

Nosivi znak se negira samo ako je prvi znak unutar izraza u zagradama; u suprotnom, gubi svoju posebnu svrhu i postaje običan lik iz skupa.

Tradicionalni rasponi znakova

Ako želimo konstruirati regularni izraz koji mora pronaći svaki fajl na našoj listi koji počinje velikim slovom, možemo učiniti sljedeće:

Grep -h "^" dirlist * .txt MAKEDEV DOBITI GLAVNI POST VBoxClient X X11 Xorg ModemManager NetworkManager VBoxControl VBoxService

Suština je da smo svih 26 velikih slova stavili u izraz unutar uglastih zagrada. Ali ideja da ih sve ispišete nije entuzijastična, pa postoji još jedan način:

Grep -h "^" dirlist * .txt

Koristeći raspon od 3 znaka, možemo skratiti unos od 26 slova. Bilo koji raspon znakova može se izraziti na ovaj način, uključujući više raspona odjednom, kao što je ovaj izraz, koji odgovara svim nazivima datoteka koji počinju slovima i brojevima:

Grep -h "^" dirlist * .txt

U rasponima znakova vidimo da se znak crtice tretira na poseban način, pa kako možemo uključiti crticu u izraz unutar uglastih zagrada? Tako što ga čini prvim znakom u izrazu. Pogledajmo dva primjera:

Grep -h "" dirlist * .txt

Ovo će odgovarati svakom imenu datoteke koje sadrži veliko slovo. pri čemu:

Grep -h "[-AZ]" dirlist * .txt

će odgovarati svakom imenu datoteke koje sadrži crticu ili veliko slovo "A" ili veliko "Z".

Regularni izrazi su vrlo moćan alat za usklađivanje uzoraka, manipulaciju i modificiranje nizova i mogu se koristiti za razne zadatke. Evo glavnih:

  • Provjera unosa teksta;
  • Pretraga i zamjena teksta u datoteci;
  • Grupno preimenovanje datoteka;
  • Interakcija sa servisima kao što je Apache;
  • Provjera niza prema uzorku.

Ovo nije potpuna lista, postoji još mnogo toga što možete učiniti s regularnim izrazima. Ali za nove korisnike, oni mogu izgledati previše komplikovano, jer se za njihovo formiranje koristi poseban jezik. Ali s obzirom na mogućnosti koje pruža, Linux regularne izraze treba da poznaje i koristi svaki administrator sistema.

U ovom članku ćemo vas provesti kroz bash regularne izraze za početnike tako da možete razumjeti sve karakteristike ovog alata.

Postoje dvije vrste znakova koji se mogu koristiti u regularnim izrazima:

  • obična pisma;
  • metakarakteri.

Regularni znakovi su slova, brojevi i znaci interpunkcije koji čine bilo koji niz. Svi tekstovi su sastavljeni od slova i možete ih koristiti u regularnim izrazima da pronađete željenu poziciju u tekstu.

Metakarakteri su nešto drugo, oni su ono što daje moć regularnim izrazima. Sa metaznakovima možete učiniti mnogo više od traženja jednog znaka. Možete tražiti kombinacije znakova, koristiti dinamički broj znakova i birati raspone. Svi specijalni znakovi se mogu podijeliti u dvije vrste, to su zamjenski znakovi, koji zamjenjuju obične znakove, ili operatori, koji označavaju koliko puta se znak može ponoviti. Sintaksa regularnog izraza će izgledati ovako:

regular_character specijalni karakter_operator

zamjena_posebnog karaktera specijalni karakter_operator

  • - doslovni specijalni znakovi počinju sa obrnutom kosom crtom, a koristi se i ako trebate koristiti poseban znak u obliku interpunkcijske oznake;
  • ^ - označava početak reda;
  • $ - označava kraj reda;
  • * - označava da se prethodni znak može ponoviti 0 ili više puta;
  • + - označava da prethodni znak treba ponoviti više od jednog ili više puta;
  • ? - prethodni znak se može pojaviti nula ili jednom;
  • (n)- označava koliko puta (n) treba ponoviti prethodni karakter;
  • (N, n)- prethodni znak se može ponoviti od N do n puta;
  • . - bilo koji znak osim prijevoda reda;
  • - bilo koji znak naveden u zagradama;
  • x | y- simbol x ili simbol y;
  • [^ az]- bilo koji znak osim onih navedenih u zagradama;
  • - bilo koji znak iz specificiranog raspona;
  • [^ a-z]- bilo koji znak koji nije u opsegu;
  • b- označava granicu riječi razmakom;
  • B- znači da znak mora biti unutar riječi, na primjer, ux odgovara uxb ili tuxedo, ali ne odgovara Linuxu;
  • d- znači da je simbol cifra;
  • D- nedigitalni karakter;
  • n- znak za prijelaz na red;
  • s- jedan od znakova razmak, razmak, tab i tako dalje;
  • S- bilo koji znak osim razmaka;
  • t- tabelarni karakter;
  • v- vertikalni tabulator;
  • w- bilo koji abecedni znak, uključujući donju crtu;
  • W- bilo koji abecedni znak osim donje crte;
  • uXXX- Unicdoe simbol.

Važno je napomenuti da se ispred specijalnih znakova literala mora koristiti kosa crta kako bi se označilo da je specijalni znak sljedeći. Važi i suprotno, ako želite da koristite poseban znak koji se koristi bez kose crte kao običan znak, onda morate dodati kosu crtu.

Na primjer, pretpostavimo da želite pronaći red 1+ 2 = 3 u tekstu. Ako ovaj string koristite kao regularni izraz, nećete ništa pronaći, jer sistem tumači plus kao poseban znak koji kaže da prethodnu jedinicu treba ponoviti jednom ili više puta. Dakle, treba ga izbaciti: 1 + 2 = 3. Bez escape-a, naš regularni izraz bi odgovarao samo nizu 11 = 3 ili 111 = 3, i tako dalje. Nema potrebe stavljati red ispred jednakosti, jer to nije poseban znak.

Primjeri korištenja regularnih izraza

Sada kada smo pokrili osnove i znate kako sve funkcioniše, ostaje da konsolidujemo stečeno znanje o linux grep regularnim izrazima u praksi. Dva vrlo korisna specijalna znaka su ^ i $, koji označavaju početak i kraj reda. Na primjer, želimo da se svi korisnici registruju u našem sistemu čije ime počinje sa s. Tada se može primijeniti regularni izraz "^ S"... Možete koristiti naredbu egrep:

egrep "^ s" / etc / passwd

Ako želimo da selektujemo linije po poslednjem znaku u retku, možemo koristiti $ za ovo. Na primjer, izaberimo sve korisnike sistema, bez ljuske, zapisi o takvim korisnicima završavaju sa false:

egrep "false $" / etc / passwd

Da biste ispisali korisnička imena koja počinju sa s ili d, koristite izraz poput ovog:

egrep "^" / etc / passwd

Isti rezultat se može dobiti upotrebom znaka "|". Prva opcija je prikladnija za raspone, a druga se češće koristi za obične ili/ili:

egrep "^" / etc / passwd

Sada izaberimo sve korisnike čije ime ima više od tri karaktera. Korisničko ime završava dvotočkom. Možemo reći da može sadržavati bilo koji abecedni znak, koji se mora ponoviti tri puta, prije dvotočka:

egrep "^ w (3):" / etc / passwd

zaključci

U ovom članku smo pokrili Linux regularne izraze, ali to su bile samo osnove. Ako zakopate malo dublje, otkrit ćete da postoji mnogo zanimljivijih stvari koje možete učiniti s ovim alatom. Vrijeme provedeno u učenju regularnih izraza definitivno će se isplatiti.

Da zaključimo, predavanje Yandexa o regularnim izrazima:

Regularni izraz- tekstualni obrazac koji se sastoji od kombinacije slova, brojeva i specijalnih znakova, poznatih kao metaznakovi. Bliski rođak regularnih izraza su džoker izrazi koji se obično koriste u upravljanju datotekama. Regularni izrazi se uglavnom koriste za poređenje teksta i pretraživanje. Široko se koristi za raščlanjivanje sintakse.

Korisnici UNIX-a su upoznati sa regularnim izrazima iz grep, sed, awk (ili gawk) i ed. Koristeći ove programe ili njihove analoge, možete pokušati i provjeriti primjere u nastavku. Uređivači teksta kao što su (X) Emacs i vi takođe intenzivno koriste regularne izraze. Možda se najpoznatija i najšira upotreba regularnih izraza javlja u jeziku Perl. Programeru softvera i administratoru sistema teško je bez poznavanja regularnih izraza.

Metakarakteri

Dakle, nizovi mogu biti sastavljeni od slova, brojeva i metakaraktera. Metakarakteri su:

\ | () { } ^ $ * + ? . < >

Metaznakovi mogu igrati sljedeće uloge u regularnom izrazu:

    kvantifikator

    izjava;

    grupni znak;

    alternativa;

    znak sekvence

Kvantifikatori

Metaznak * (zvjezdica) zamjenjuje 0 ili više znakova. Metaznak + (plus) zamjenjuje 1 ili više znakova. Metacharacter. (tačka) zamjenjuje tačno 1 proizvoljan znak. metakarakter? (znak pitanja) zamjenjuje 0 ili 1 znak. Razlika u upotrebi * i + je takva da će upit za pronalaženje stringa sa * vratiti sve nizove, uključujući i prazne, a upit sa + će vratiti samo nizove koji sadrže znak c.

Prazni redovi poštuju sljedeće konvencije: Prazan red sadrži jedan i samo jedan prazan red; red koji nije prazan sadrži prazne redove ispred svakog znaka i takođe na kraju reda.

Regularni izrazi također koriste (n, m) konstrukciju, što znači da se znak koji prethodi konstrukciji pojavljuje n do m puta u nizu. Izostavljanje broja m znači beskonačnost. One. posebni slučajevi konstrukcije su sljedeći unosi: (0,), (1,) i (0,1). Prvi odgovara *, drugi odgovara metakaku +, a treći odgovara? ... Ove je jednakosti lako dobiti iz definicije odgovarajućih kvantifikatora. Osim toga, konstrukcija (n) znači da se simbol pojavljuje tačno n puta.

U vezi sa upotrebom nekih interpunkcijskih znakova i matematičkih simbola kao metakaraktera, uveden je dodatni metaznak \ (obrnuta kosa crta, obrnuta kosa crta) koji, kada se napiše ispred metaznaka, pretvara ovaj drugi u običan znak. One. ? je kvantifikator, a \? - upitnik.

Grupe

Gore opisani kvantifikatori, kao što je već spomenuto, djeluju na lik koji im je najbliži s lijeve strane (posljednji prethodni). Ali ovo ograničenje vam omogućava da zaobiđete grupe u označavanju metakaraktera (i). Ovi znakovi izdvajaju podizraz iz izraza, grupiranog u grupu, na koji se zatim primjenjuje kvantifikator.

primjer:

znači (ili zamjenjuje)

Ho ho ho ho ho ho hoho

Moguće je ugniježđenje podizraza, tj. kraći podizrazi se mogu izdvojiti iz podizraza.

Alternative

Formirano pomoću metaznaka | (vertikalna traka) koja označava logično "ili".

Primjer: regularni izraz krave (a | s | e | y | ups | oyu)? specificira sve moguće deklinacije riječi "krava" u jednini za padeže.

Tvrdnje

Dodeljuju se metaznakovi koji označavaju posebne objekte - nizove nulte dužine, koji se koriste za određivanje mesta teksta koji im prethodi ili sledi. Takvi objekti se nazivaju iskazi. Sljedeće izjave postoje u regularnim izrazima:

^ početak reda $ kraj reda< начало слова >kraj riječi

Primjer: regularni izraz $ Podudara se sa nizom koji počinje sa The.

Napomena: Uobičajeni znakovi se mogu posmatrati kao iskazi koji nisu nulte dužine.

Sekvence

Posebna konstrukcija, zatvorena u metaznake [i] (uglate zagrade), omogućava vam da navedete varijante znakova koji se mogu pojaviti u regularnom izrazu na datom mjestu, a naziva se niz. Unutar uglastih zagrada, svi metaznakovi se tretiraju kao jednostavni simboli, a simboli - (minus) i ^ dobijaju nova značenja: prvi vam omogućava da navedete kontinuirani niz znakova između dva navedena, a drugi daje logično "ne" ( negacija). Sljedeće primjere je najlakše razmotriti:

bilo koje od malih latiničnih slova:

latinični alfanumerički znak (a do z, od A do Z i 0 do 9):

nelatinski alfanumerički znak:

[^ a-zA-Z0-9]

bilo koju riječ (bez crtica, matematičkih simbola i brojeva):

<+>

Radi sažetosti i jednostavnosti uvode se sljedeće skraćenice:

\ d cifra (tj. odgovara izrazu); \ D nije cifra (tj. [^ 0-9]); \ w latinična riječ (alfanumerička); \ W je niz znakova bez razmaka koji nije latinična alfanumerička riječ ([^ a-zA-Z0-9]); \ s prazan prostor [\ t \ n \ r \ f], tj razmaci, tabulatori itd. \ S je neprazan raspon ([^ \ t \ n \ r \ f]).

Odnos sa zamjenskim znakovima

Svaki korisnik je vjerovatno upoznat sa zamjenskim znakovima. Primjer džoker izraza je * .jpg, koji označava sve datoteke sa ekstenzijom jpg. Po čemu se regularni izrazi razlikuju od zamjenskih znakova? Razlike se mogu sažeti u tri pravila za pretvaranje proizvoljnog džoker izraza u regularni izraz:

    Zamijenjeno sa.*

    Zamijeniti? on.

    Zamijenite sve znakove koji odgovaraju metakarakterima njihovim varijantama obrnute kose crte.

Zaista, u regularnom izrazu pisanje * je beskorisno i daje prazan string, jer znači da se prazan niz ponavlja bilo koji broj puta. I ovdje.* (Ponovite proizvoljan znak koliko god puta želite, uključujući 0) tačno se podudara po značenju sa * znakom u skupu zamjenskih znakova.

Regularni izraz koji odgovara * .jpg će izgledati ovako: * \. Jpg. Na primjer, sekvence zamjenskih znakova ez * .pp odgovaraju dva ekvivalentna regularna izraza, ez. * \. Pp i ez. * \. (Cpp | hpp).

Primjeri regularnog izraza

E-mail u formatu [email protected]

+(\.+)*@+(\.+)+

E-mail u formatu „Ivan Ivanov "

("? +"? [\ t] *) + \<+(\.+)*@+(\.+)+\>

Provjera web protokola u URL-u (http: //, ftp: // ili https: //)

+://

Neke C / C ++ naredbe i direktive:

^ # uključiti [\ t] + [<"][^>"] + [">] - uključuje direktivu

//.+$ - komentar u jednom redu

/ \ * [^ *] * \ * / - komentar na nekoliko redaka

-? + \. + - broj u pokretnom zarezu

0x + je heksadecimalni broj.

A evo, na primjer, programa za pronalaženje riječi krava:

grep -E "krava | vache" *> / dev / null && echo "Pronađena krava"

Ovdje se opcija -E koristi za omogućavanje proširene podrške za sintaksu regularnog izraza.

Ovaj tekst je zasnovan na članku Jana Borsodija iz datoteke HOWTO-regexps.htm

Kontinuirani izraz je obrazac koji opisuje skup nizova. Regularni izrazi se konstruiraju slično aritmetičkim izrazima, koristeći različite operatore za kombiniranje manjih izraza.

Kontinuirani izrazi (engleski regularni izrazi, skraćeno RegExp, RegEx, jarg. Regexps ili regexes) je sistem za raščlanjivanje fragmenata teksta prema formalizovanom šablonu, zasnovan na sistemu pisanja obrazaca za pretragu. Obrazac definira pravilo pretraživanja, na ruskom se ponekad klikne i "uzorak", "maska". Regularni izrazi su napravili proboj u elektronskoj obradi sadržaja krajem 20. stoljeća. Oni su predstavljeni razvojem zamjenskih znakova.

Konstantne izraze sada koriste brojni uređivači teksta i uslužni programi za pronalaženje i modificiranje teksta na osnovu odabranih pravila. Gotovo mnogi programski jezici podržavaju regularne izraze za manipulaciju stringovima. Na primjer, Java, .NET Framework, Perl, PHP, JavaScript, Python i drugi imaju ugrađenu podršku za konstantne izraze. Skup uslužnih programa (uključujući sed editor i grep filter) koje UNIX distribucije smatraju jednim od najranijih pomogao je popularizaciji koncepta regularnih izraza.

Jedna od korisnijih i korisnijih komandi u Linux terminalu je "grep" brigada. Grep je akronim koji je skraćenica za "global regular expression print" (to jest, "tražite svuda nizove koji odgovaraju konstantnom izrazu i odštampajte ih").

To znači da možete koristiti grep da vidite da li vaš unos odgovara datom uzorku. U svom najjednostavnijem obliku, grep se koristi za pronalaženje podudaranja za uzorke slova u tekstualnoj datoteci. To znači da ako grep dobije riječ za pretraživanje, ispisat će svaki red u datoteci koja pohranjuje tu riječ.

Svrha grep-a je da traži nizove prema uslovu regularnog izraza. Postoje promjene u klasičnom grep-u - egrep, fgrep, rgrep. Svi su fino podešeni za specifične svrhe, dok mogućnosti grepa preklapaju svu funkcionalnost. Najjednostavniji primjer korištenja naredbe je izlaz niza koji odgovara uzorku iz datoteke. Primjer želimo da pronađemo liniju koja pohranjuje 'korisnika' u /etc/mysql/my.cnf datoteci. Da bismo to uradili, koristićemo sledeću naredbu:

Grep korisnik /etc/mysql/my.cnf

Grep može jednostavno tražiti određenu riječ:

Grep Zdravo ./example.cpp

Ili niz, ali u ovom slučaju mora biti stavljen u navodnike:

Grep "Hello world" ./example.cpp

Osim toga, alternative programu su egrep i fgrep, koji su isti kao grep -E i grep -F, respektivno. Okusi egrep i fgrep su zastarjeli, ali rade na kompatibilnosti unatrag. Preporučljivo je koristiti grep -E i grep -F umjesto zastarjelih opcija.

Naredba grep uparuje linije izvornih datoteka sa šablonom, ovim osnovnim regularnim izrazom. Ako nije navedena nijedna datoteka, koristi se standardni unos. Kao i obično, svaka uspješno uparena linija se kopira u standardni izlaz; ako
malo izvornih datoteka, ime datoteke se ispisuje prije pronađenog reda. Osnovni kontinuirani izrazi (izrazi koji imaju nizove znakova kao svoje značenje i koriste ograničen raspon alfanumeričkih i specijalnih znakova) prihvaćaju se kao predlošci.

Korištenje egrep-a u Linuxu

Egrep ili grep -E je drugačija verzija grep ili Extended grep. Ova verzija grep-a je odlična i brza kada je u pitanju traženje šablona regularnog izraza, jer tretira metakaraktere kakve jesu i ne zamjenjuje ih kao nizove. Egrep koristi ERE ili Extended Extended Expression.

egrep je skraćeni poziv za grep sa prekidačem -E. Razlikuje se od grep po mogućnosti korištenja proširenih kontinuiranih izraza korištenjem POSIX klasa znakova. Često se javlja problem pronalaženja riječi ili reprezentacija koje pripadaju istom tipu, ali sa mogućim varijacijama u pisanju, kao što su datumi, nazivi datoteka sa nekim ekstenzijom i standardnim imenom, e-mail adrese. S druge strane, postoje zadaci za pronalaženje dobro definiranih riječi koje mogu imati različite oblike ili pretraživanje koje isključuje pojedinačne znakove ili klase znakova.

Za ove svrhe, neki sistemi su kreirani na osnovu opisa teksta pomoću šablona. Konstantni izrazi su takođe rangirani među takvim sistemima. Dva vrlo korisna specijalna znaka su ^ i $, koji označavaju početak i kraj reda. Na primjer, želimo da se svi korisnici registruju u našem sistemu čije ime počinje sa s. Tada se može primijeniti regularni izraz "^ s". Možete koristiti egrep brigadu:

Egrep "^ s" / etc / passwd

Moguće je pretraživati ​​više fajlova iu tom slučaju ime fajla se prikazuje ispred reda.

Egrep -i Zdravo ./example.cpp ./example2.cpp

I sljedeći upit prikazuje sav kod, isključujući redove koji sadrže samo komentare:

Egrep -v ^ / ./example.cpp

Kao egrep, čak i ako ne izbjegavate metakaraktere, naredba će ih tretirati kao posebne znakove i zamijeniti ih njihovim posebnim značenjem umjesto da ih tretira kao dio niza.

Korištenje fgrep na Linuxu

Fgrep ili Fiksni grep ili grep -F je još jedna verzija grep-a koja nije potrebna kada je u pitanju pretraživanje cijele linije umjesto regularnog koncepta, jer ne prepoznaje regularne izraze ili metakaraktere. Za direktno traženje bilo koje linije odaberite ovu verziju grep-a.

Fgrep traži kompletan string i ne prepoznaje posebne znakove kao dio kontinuiranog izraza, bez obzira da li su znakovi escapeirani ili ne.

Fgrep -C 0 "(f | g) ile" check_file fgrep -C 0 "\ (f \ | g \) ile" check_file

Korištenje sed-a na Linuxu

sed (od engleskog Stream EDitor) je uređivač teksta za strujanje (kao i programski jezik) koji koristi različite unaprijed definirane transformacije teksta u sekvencijalni tok tekstualnih. Sed se može ukloniti kao grep, izlazeći linije slijedeći obrazac osnovnog redovnog izraza:

Sed -n / Zdravo / p ./example.cpp

Može se koristiti za brisanje redova (ukloniti sve prazne redove):

Sed / ^ $ / d ./example.cpp

Glavni alat za rad sa sed-om je izraz poput:

Sed s / lookup_expression / what_replace / filename

Dakle, primjer, ako pokrenete naredbu:

Sed s / int / long / ./example.cpp

Razlike između "grep", "egrep" i "fgrep" su razmotrene gore. Bez obzira na razlike u skupu regularnih reprezentacija koje se koriste i brzini izvršavanja, opcije komandne linije ostaju iste za sve tri verzije grep-a.

Podijelite ovo