Jeg observerer følgende oppførsel av grep når du kjører den fem ganger:

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$ 

Jeg kunne ikke forstå hvorfor de to siste forsøkene med grep ikke gir noe resultat .

Svar

grep mønstre er vanlige uttrykk (aka regex, regexp, RE), grunnleggende regulære uttrykk (BRE) med mindre en av -E / -F / -P / -K / -X alternativet (bare de to første som er standard) brukes.

* er en regexp-operator som samsvarer med 0 eller flere av forrige atom . For eksempel d* samsvarer med 0 eller flere d s. I BRE, når du begynner på mønsteret eller når du følger

eller \( regexp-operatører, den samsvarer med en bokstavelig * (den er også tatt bokstavelig talt i [...] parentesuttrykk).

grep "*README.md*" samsvarer med linjer som inneholder en bokstavelig * etterfulgt av README etterfulgt av et enkelt tegn (. regexp-operatøren) etterfulgt av m etterfulgt av et hvilket som helst antall d s. Siden et hvilket som helst tall inkluderer 0, betyr det at «s funksjonelt tilsvarer grep "*README.m" (noe som ikke gjør noen forskjell for hvilke linjer som blir matchet, bare på det som kan matches. innenfor linjen (som vises med --color alternativet til GNU grep for eksempel)).

For eksempel , ville det matche på de to linjene:

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

(^ viser hva innenfor linjen samsvarer av det regulære uttrykket, som du kunne se med --color)

Her ser det ut til at du forveksler vanlige uttrykk med skall-jokertegnmønstre. * jokertegnoperatøren som samsvarer med 0 eller flere tegn, kan skrives .* i vanlige uttrykk. Men å gjøre:

grep ".*README\.md.*" 

ville igjen være det samme som:

grep "README\.md" 

Som grep ser etter et samsvar innenfor linjen i motsetning til å finne linjer som samsvarer med mønsteret nøyaktig (som du trenger -x).

Med ast-åpen grep, som også er ksh93 «s grep innebygd (ikke alltid innebygd som standard, og du må aktivere det ved å sette /opt/ast/bin foran $PATH), kan du bruke -K -alternativet for grep til å bruke shell-jokertegn (utvidede ksh93-ens). Så med det «abd75beda0″>

implementering, du kan gjøre:

grep -K "README.md" 

eller

grep -xK "*README.md*" 

for å matche på linjer som inneholder README.md.

Med den samme implementeringen kan jokertegnetilpasning også aktiveres innen utvidet (), augmented (-X) eller perl-lignende (-P) uttrykk med operatøren (?K) (og \(?K\) i grunnleggende regulære uttrykk som faktisk bryter POSIX-samsvar, så jeg vil ikke stole på det som det kan fjernes i en fremtidig versjon). Så du kan gjøre:

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

der.

Med enhver moderne grep implementering, du kan også gjøre:

grep -F README.md 

For et fast strengesøk (der . ovenfor samsvarer med en bokstavelig . i stedet for hvilket som helst tegn).

Kommentarer

  • FWIW: Perl klager over * eller + i starten av regex, og det gjør grep -P
  • @ilkkachu , det gjør grep -E med flere implementeringer. At * behandles bokstavelig når i begynnelsen, er bare spesifisert for BRE. Med andre RE-er, YMMV.
  • @St é phaneChazelas Jeg fant ikke ' t spesifikasjonen for den ledende stjernen . Er det dokumentert hvor som helst? Jeg ' m bruker vanlig grep (eller grep -G) også.
  • @iBug, hvis du setter svaret mer nøye, ' vil du legge merke til hva (jeg tror) du ' refererer til er for ast-åpen ' s grep -K som bruker skallmønstre (der * samsvarer med et hvilket som helst antall tegn).
  • @iBug, hvis du mener * ikke er spesiell når det første tegnet i en BRE, se POSIX-spesifikasjonen

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *