Observ următorul comportament al lui grep când îl rulez de cinci ori:

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$ 

Nu am putut înțelege de ce ultimele două încercări ale grep nu returnează niciun rezultat .

Răspuns

grep sunt expresii regulate (aka regex, regexp, RE), de bază expresii regulate (BRE) cu excepția cazului în care una dintre -E / -F / -P / -K / -X este utilizată opțiunea (dintre care numai primele două fiind standard).

* este un operator regexp care se potrivește cu 0 sau mai multe din atom precedent. De exemplu, d* se potrivește cu 0 sau mai multe d s. În BRE-uri, când se află la începutul modelului sau când se urmărește

sau \( operatori regexp, se potrivește doar cu un literal * (este, de asemenea, luat literalmente în interiorul [...] expresii paranteze).

Deci grep "*README.md*" se potrivește pe liniile care conțin un literal * urmat de README urmat de orice caracter unic (. operator regexp) urmat de m urmat de orice număr de d. Deoarece orice număr include 0, acest lucru este „echivalent din punct de vedere funcțional cu grep "*README.m" (ceea ce nu ar face nicio diferență cu care linii sunt potrivite, doar pe ceea ce poate fi egalat în cadrul liniei (care s-ar afișa cu opțiunea --color a GNU grep de exemplu)).

De exemplu , s-ar potrivi pe acele 2 rânduri:

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

(^ arată ce se potrivește în linie prin expresia regulată, pe care ați putea-o vedea cu --color)

Aici, se pare că confundați expresiile regulate cu tiparele de caractere wildcard. * operatorul comodin care se potrivește pe 0 sau mai multe caractere poate fi scris .* în expresii regulate. Dar a face:

grep ".*README\.md.*" 

ar fi din nou același lucru ca:

grep "README\.md" 

Ca grep caută o potrivire în linie spre deosebire de găsirea liniilor care se potrivesc exact cu modelul (pentru care aveți nevoie de -x).

Cu ast-open grep, care este și ksh93 „s grep builtin (nu întotdeauna încorporat în mod implicit și trebuie să îl activați punând /opt/ast/bin înaintea $PATH), puteți utiliza opțiunea -K pentru grep pentru a folosi metacaractere shell (cele ksh93 extinse). Deci, cu acel grep implementare, puteți face:

grep -K "README.md" 

sau

grep -xK "*README.md*" 

pentru a se potrivi pe liniile care conțin README.md.

Cu aceeași implementare, potrivirea wildcard poate fi activată și în extins (), augmentat (-X) sau perl-like (-P) regulat expresii cu operatorul (?K) (și \(?K\) în expresii regulate de bază care de fapt încalcă conformitatea POSIX, așa că nu m-aș baza pe ea în timp ce poate fi eliminat într-o versiune viitoare). Deci puteți face:

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

acolo.

Cu orice implementare modernă grep, puteți face, de asemenea:

grep -F README.md 

Pentru o căutare cu șir fix (unde . de mai sus se potrivește cu un literal . în loc de orice caracter).

Comentarii

  • FWIW: Perl se plânge de * sau + la începutul regexului, la fel și grep -P
  • @ilkkachu , la fel și grep -E cu mai multe implementări. Acel * tratat literal atunci când la început este specificat doar pentru BRE-uri. Cu alte RE-uri, YMMV.
  • @St é phaneChazelas ' nu am găsit specificația pentru asteriscul principal . Este documentat undeva? ' m folosesc și simplu grep (sau grep -G).
  • @iBug, dacă citiți răspunsul mai atent, ' veți observa ceea ce (cred) ' se referă la este pentru ast-open ' s grep -K care folosește modele de shell (unde * se potrivește cu orice număr de caractere).
  • @iBug, dacă vrei să spui * nefiind special atunci când primul caracter al unui BRE, vezi specificația POSIX

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *