6  *grep & regular expressions

6.1  Yleistä

Monet Unix-komennot tarvitsevat yleistä merkkijonovertailua, keinoa kysyä ''kuuluuko merkkijono x joukkoon X?'' Tähän tarkoitukseen käytetään merkkijonomalleja, erikoismerkkejä sisältäviä merkkijonoja, jotka vastaavat tiettyjen sääntöjen mukaisesti joukkoa merkkijonoja. Yksi yleinen tällainen on regular expression, formaalien kielten teoriasta lainattu termi jolle ei ole oikein hyvää suomennosta.

Historiallisista syistä eri komennot käyttävät erilaisia ja yhteensopimattomia merkkijonomalleja:

Jotkin komennot käyttävät vielä edellisistä poikkeavia malleja, yleensä edellisiä jotenkin rajoitettuina, esim. tr. Huomionarvoinen on myös case-lauseen syntaksiin kuuluva |, joka olennaisesti laajentaa sen ymmärtämää GP:tä, vaikka muodollisesti onkin eri asia.

Lisäksi monet epästandardit komennot käyttävät omia versioitaan, lähinnä erilaisia laajennuksia edellisiin. Erityisesti ksh tuntee omat laajennuksensa GP:hen () ja Gnu-versiot standardikomennoista tuntevat erinäisiä regexp-laajennuksia, samoin perl.

6.2  grep - File pattern searcher

Komento grep ja käsite regular expression liittyvät kiinteästi yhteen, sen nimikin on lyhenne ed-editorin syntaksista: Global/RegExp/Print. Sen syntaksi on seuraavanlainen:

grep [-E|-F] [-c|-l|-q] [-insvx] [[-e] pattern_list...] [-f pattern_file...] [file...]

ja se etsii tiedostosta annettua mallia (-eja) vastaavia rivejä. Oletuksena malli (pattern) on basic regular expression (BRE), mistä enemmän alla, ja (vain) mallia vastaavat rivit (rivit joilla esiintyy mallia vastaava merkkijono) tulostetaan.

Optiot:

-E Käytä laajennettua regexp syntaksia (extended regular expression, ERE).
-F Etsi vakiomerkkijonoa (ei regexp).
-c Tulosta vain löydettyjen rivien lukumäärä.
-e pattern_list Etsittävät mallit (komentoriviargumentteina).
-f pattern_file Lue etsittävät mallit tiedostosta, yksi per rivi.
-i Samaista isot ja pienet kirjaimet.
-l Tulosta vain niiden tiedostojen nimet, joista malli löytyi.
-n Tulosta rivinumerot löydetyille riveille (kunkin tiedoston alusta ykkösellä alkaen).
-q Älä tulosta mitään.
-s Ei virhettä tiedostoista joita ei voi lukea tai joita ei ole.
-v Tulosta vain rivit jotka eivät vastaa mallia.
-x Tulosta vain rivit jotka kokonaisuudessaan vastaavat mallia.

Optioita -e ja -f voi antaa useita. Jos kumpaakaan ei ole annettu, ensimmäinen ei-optio argumentti tulkitaan malliksi. (Siten -e on tarpeen vain jos malleja halutaan antaa useita tai malli alkaa viivalla (vrt. --).) Kussakin tapauksessa useita malleja voidaan antaa erottamalla ne rivinvaihdolla (grep on tiukasti rivipohjainen, rivinvaihtoja sisältäviä malleja ei voi käyttää).

Jos tiedostoargumentteja on useita, grep tulostaa tiedostonimet kustakin tiedostosta löytyvien rivien (tai löydettyjen rivien lukumäärän optiolla -c) alkuun kaksoispisteellä erotettuna (optiolla -l aina vain tiedostonimet).

Exit status on 0 jos ainakin yksi mallia vastaava rivi löytyi, 1 jos ei, > 1 jos tapahtui virhe (paitsi optiolla -q nolla myös virheen tapahtuessa jos rivi löytyi).

Komennosta on historiallisesti myös versiot egrep ja fgrep, jotka toimivat kuten grep -E ja grep -F.

6.3  Basic Regular Expressions

BRE:t tulkitaan seuraavien sääntöjen mukaisesti:

Erikoismerkit tulkitaan seuraavan prioriteettijärjestyksen mukaisesti:

  1. [= =] [: :] [. .]
  2. \<erikoismerkki>
  3. [...]
  4. \( \) \n
  5. * ja \{m[,n]\}
  6. yhdistely
  7. ^ ja $ ankkureina

Useasta mahdollisesta osamerkkijonosta BRE vastaa ensimmäistä (vasemmanpuoleisinta), jos niitä on useita pisintä niistä. Tällä ei ole merkitystä grepin kanssa mutta esim. sedin ja exprin kanssa kylläkin.

Kenoviivan vaikutusta muiden kuin edellämainittujen merkkien edellä ei ole määritelty, ja se vaihtelee järjestelmästä toiseen.

Huom. Rivinvaihdolla ei ole mitään erityisasemaa RE:ssä sinänsä, vaikka monet komennot moisen rajoituksen asettavatkin (mutta esim. sed ei).

Kaiken mitä voi tehdä GP:llä voi tehdä BRE:lläkin, mutta ei päinvastoin. Seuraavassa taulukossa on esimerkkejä niiden eroista:

GP BRE
? .
* .*
a* a.*
a.* a\..* tai a[.].*
*[!0-9]* .*[^ 0-9].*
^ ?^ \^ .^
\? ?
\*a *a
[0-9][0-9][0-9][0-9] [0-9]\{4\}

Seuraavassa taulukossa on BRE:llä ja ksh:n GP:llä esimerkkejä malleista joita ei perus-GP:llä voi tehdä:

BRE ksh GP
[-+]\{0,1}[0-9][0-9]* ?([-+])+([0-9])
[A-Za-z][A-Za-z0-9_]* [A-Za-z]*([A-Za-z0-9_])
[0-9]\{1,3\} [0-9]?([0-9])?([0-9])
\([[:alpha:]]\)[[:blank:].,]\1 (ei onnistu)
(ei onnistu) ?(Kalle|Pekka|Tapani)

Viimemainittu ei siis onnistu BRE:llä lainkaan, seuraavassa esiteltävällä ERE:llä kylläkin. Myös case-lauseella se onnistuu helposti.

6.4  Extended Regular Expressions

ERE:t tulkitaan muuten samoin kuin BRE:t paitsi:

Erikoismerkkien prioriteetti on soveltuvin osin sama:

  1. [= =] [: :] [. .]
  2. \<erikoismerkki>
  3. [...]
  4. ( )
  5. * + ? ja {m[,n]}}
  6. yhdistely
  7. ^ ja $ ankkureina
  8. |

Olennainen lisä BRE:hen on tai-operaattori | ja olennainen heikkous osalausekeviittauksen (\n) puuttuminen. Seuraavassa esimerkkejä eroista:

BRE ERE
[-+]\{0,1\}[0-9][0-9]* [-+]?[0-9]+
[-+]\{0,1\}[0-9]\{1,10\} [-+]?[0-9]{1,10}
\(/[a-zA-Z0-9]\{1,14\}\)\{1,\} (/[a-zA-Z0-9]{1,14})+
\([[:alpha:]]\)[[:blank:].,]\1 (ei onnistu)
(ei onnistu) Kalle|Pekka|Tapani

Siis joitakin asioita voi tehdä vain BRE:llä ja joitakin vain ERE:llä. (Tosin esim. Gnu grep kyllä tuntee osalausekeviittauksen myös ERE:n kanssa.) Teoriassa ksh:n GP on yhtä ilmaisuvoimainen kuin ERE, käytännössä usein paljon hankalampi (erityisesti toisto-operaattorin puutteen vuoksi).

6.5  Esimerkkejä

Toisinaan käytettävä komento ratkaisee millaista merkkijonomallia on käytettävä, mutta grep tuntee kaksi erilaista ja usein saman asian voi tehdä monella eri komennolla jotka käyttävät erilaisia malleja. Seuraavassa esimerkkejä valinnan avuksi.

6.6  Gnu extensions

Gnu-projektin komennot tuntevat joukon laajennuksia BRE/ERE-syntaksiin:

\ < sanan alku
\ > sanan loppu
\b sanan raja (alku tai loppu)
\B muu kuin sanan raja
\w kirjain tai numero ([[:alnum:]])
\W sama kuin [^ [:alnum:]]
\| BRE:ssä sama kuin | ERE:ssä

\ < , \ > , \b ja \B vastaavat nollamittaista merkkijonoa ao. paikassa, ts. toimivat ankkureina ^ :n ja $:n tapaan. Lisäksi osalausekeviittaukset toimivat myös ERE:ssä. (Siis Gnu ERE ja BRE ovat toiminnallisesti identtisiä, ainoa ero on syntaksissa.)

Gnu grep tuntee myös joukon epästandardeja optioita ja pitkiä synonyymejä standardioptioille. Niihin ei tässä puututa sen enempää.

Seuraava: 7. sed
Edellinen: 5.44-72 Standardikomennot N-Z


File translated from TEX by TTH, version 1.98.
On 17 May 2001, 18:14.