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).
*
tai+
regexin alussa, samoingrep -P
grep -E
useilla toteutuksilla.*
, jota kohdellaan kirjaimellisesti, kun alussa määritetään vain BRE: lle. Muiden RE-laitteiden kanssa YMMV.grep
(taigrep -G
).grep -K
, joka käyttää kuorimalleja (missä*
vastaa mitä tahansa merkkien määrää).*
ei ole erityinen, kun BRE: n ensimmäinen merkki, katso POSIX-määritys