Havaitsen seuraavan grep -käytön, kun sitä ajetaan viisi kertaa:

me@asus:~/go/src/company/topology-front$ lsof |grep "READ" vim 4788 me 4u REG 8,2 12288 32247694 /home/me/go/src/company/topology-front/.README.md.swp me@asus:~/go/src/company/topology-front$ lsof |grep "README.md*" vim 4788 me 4u REG 8,2 12288 32247694 /home/me/go/src/company/topology-front/.README.md.swp me@asus:~/go/src/company/topology-front$ lsof |grep "README.md" vim 4788 me 4u REG 8,2 12288 32247694 /home/me/go/src/company/topology-front/.README.md.swp me@asus:~/go/src/company/topology-front$ lsof |grep "*README.md*" me@asus:~/go/src/company/topology-front$ lsof |grep "*README.md" me@asus:~/go/src/company/topology-front$ 

En voinut ymmärtää, miksi grep kaksi viimeistä yritystä eivät palauta tulosta .

Vastaus

grep mallit ovat säännöllisiä lausekkeita (alias regex, regexp, RE), perus säännölliset lausekkeet (BRE), ellei jokin seuraavista -E / -F / -P / -K / -X vaihtoehtoa (joista vain kaksi ensimmäistä vakiona) käytetään.

* on regexp-operaattori, joka vastaa 0 tai useampaa edellisestä atomista . Esimerkiksi d* vastaa 0 tai enemmän d s. BRE-tiedostoissa, kun kuvion alussa tai kun seuraa

tai \( regexp -operaattorit, se vastaa vain kirjaimellisia * (se otetaan myös kirjaimellisesti [...] hakasulkeissa).

Joten grep "*README.md*" vastaa riviä, jotka sisältävät kirjaimellisen *, jota seuraa README, jota seuraa mikä tahansa yksittäinen merkki (. regexp -operaattori), jota seuraa m, jota seuraa mikä tahansa määrä d s. Koska mikä tahansa numero sisältää 0, se on toiminnallisesti sama kuin grep "*README.m" (mikä ei merkitsisi mitään eroja rivien kanssa, jotka sovitetaan, vain siihen, mikä voidaan sovittaa) rivillä (joka näkyy esimerkiksi GNU --color -vaihtoehdolla grep)).

Esimerkiksi , se sopisi näihin kahteen riviin:

*README mike ^^^^^^^^^ DONT***README-mddd ^^^^^^^^^^^^ 

(^ s, jotka osoittavat, mitä rivin sisällä on säännöllisen lausekkeen avulla, jonka voit nähdä --color)

Tässä näyttää siltä, että sekoitat säännölliset lausekkeet kuoren yleismerkkeihin. * jokerimerkkioperaattori, joka vastaa vähintään 0 merkkiä, voidaan kirjoittaa .* säännöllisiin lausekkeisiin. Mutta tekeminen:

grep ".*README\.md.*" 

olisi jälleen sama kuin:

grep "README\.md" 

Kuten grep etsii osumaa riviltä sen sijaan, että löydettäisiin linjat, jotka sopivat tarkalleen kuvioon (jota varten tarvitset -x).

Ast-open grep, joka on myös ksh93 ”s grep sisäänrakennettu (ei aina sisäänrakennettu oletusarvoisesti, ja sinun on otettava se käyttöön asettamalla /opt/ast/bin $PATH), voit käyttää -K -vaihtoehtoa kohteelle grep käyttääksesi jokerimerkkejä (laajennettuja ksh93-nimisiä). Joten tämän kanssa grep käyttöönotto, voit tehdä:

grep -K "README.md" 

tai

grep -xK "*README.md*" 

vastaamaan rivillä, jotka sisältävät README.md.

Samalla toteutuksella jokerimerkinnät voidaan ottaa käyttöön myös laajennetuissa (), lisätty (-X) tai perl-tyyppinen (-P) säännöllinen lausekkeet, joissa on (?K) -operaattori (ja \(?K\) säännöllisissä peruslausekkeissa, jotka todella rikkovat POSIX-yhteensopivuuden, joten en luottaisi siihen, koska se voidaan poistaa tulevassa versiossa). Joten voit tehdä:

grep -xE "(?K)*README.md*" 

siellä.

Kaikilla moderneilla grep -toteutuksilla, voit myös tehdä:

grep -F README.md 

Kiinteän merkkijonohakua varten (jossa yllä oleva . vastaa kirjaimellista . minkä tahansa merkin sijaan).

Kommentit

  • FWIW: Perl valittaa * tai + regexin alussa, samoin grep -P
  • @ilkkachu , samoin grep -E useilla toteutuksilla. *, jota kohdellaan kirjaimellisesti, kun alussa määritetään vain BRE: lle. Muiden RE-laitteiden kanssa YMMV.
  • @St é phaneChazelas En löytänyt ' t etsimässä johtava tähti-erittelyä . Onko se dokumentoitu missään? Käytän ' m myös tavallista grep (tai grep -G).
  • @iBug, jos kielet vastauksen huolellisemmin, ' huomaat, mitä (mielestäni) ' viittaus koskee ast-open ' s grep -K, joka käyttää kuorimalleja (missä * vastaa mitä tahansa merkkien määrää).
  • @iBug, jos tarkoitat, että * ei ole erityinen, kun BRE: n ensimmäinen merkki, katso POSIX-määritys

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *