Ik observeer het volgende gedrag van grep wanneer het wordt uitgevoerd vijf keer:

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$ 

Ik kon niet “begrijpen waarom de laatste twee pogingen van grep geen resultaat opleveren .

Answer

grep patronen zijn reguliere expressies (ook wel regex, regexp, RE), standaard reguliere expressies (BRE) tenzij een van -E / -F / -P / -K / -X optie (waarvan alleen de eerste twee standaard zijn) wordt gebruikt.

* is een regexp-operator die overeenkomt met 0 of meer van het voorgaande atoom . Bijvoorbeeld d* komt overeen met 0 of meer d s. In BREs, wanneer aan het begin van het patroon of wanneer de

of \( regexp-operators, het komt overeen met een letterlijke * alleen (deze wordt ook gebruikt letterlijk binnen [...] expressies tussen haakjes).

Dus grep "*README.md*" komt overeen met regels die een letterlijke * gevolgd door README gevolgd door een willekeurig teken (de . regexp-operator) gevolgd door m gevolgd door een willekeurig aantal d s. Aangezien elk getal 0 bevat, is dat functioneel equivalent aan grep "*README.m" (wat geen verschil zou maken aan welke regels worden gekoppeld, alleen op wat mogelijk overeenkomt binnen de regel (die zou worden weergegeven met de --color optie van GNU grep bijvoorbeeld)).

Bijvoorbeeld , zou het overeenkomen op die 2 regels:

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

(de ^ s laten zien wat er binnen de regel overeenkomt door de reguliere expressie, die je zou kunnen zien met --color)

Hier lijkt het erop dat je reguliere expressies verwart met shell-jokertekens. De * jokertekenoperator die overeenkomt met 0 of meer tekens, kan in reguliere expressies worden geschreven .*. Maar doen:

grep ".*README\.md.*" 

zou weer hetzelfde zijn als:

grep "README\.md" 

Als grep zoekt naar een overeenkomst binnen de regel in plaats van regels te vinden die exact overeenkomen met het patroon (waarvoor u -x).

Met ast-open grep, wat ook ksh93 “s ingebouwd (niet altijd standaard ingebouwd, en u moet het inschakelen door /opt/ast/bin voor $PATH), kunt u de -K optie voor grep gebruiken om shell-jokertekens te gebruiken (uitgebreide ksh93-tekens). Dus met die grep implementatie, kunt u doen:

grep -K "README.md" 

of

grep -xK "*README.md*" 

om te matchen op regels die README.md bevatten.

Met dezelfde implementatie kan het matchen van jokertekens ook worden ingeschakeld binnen extended (), augmented (-X) of perl-achtig (-P) normaal expressies met de (?K) operator (en \(?K\) in reguliere reguliere expressies die in feite POSIX-conformiteit verbreken, dus ik zou er niet op vertrouwen zoals kan worden verwijderd in een toekomstige versie). Dus je kunt het volgende doen:

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

daar.

Met elke moderne grep implementatie, u kunt ook het volgende doen:

grep -F README.md 

Voor een zoekopdracht met een vaste tekenreeks (waarbij . hierboven overeenkomt met een letterlijke . in plaats van een willekeurig teken).

Reacties

  • FWIW: Perl klaagt over * of + aan het begin van de reguliere expressie, en dat geldt ook voor grep -P
  • @ilkkachu , net als grep -E met verschillende implementaties. Dat * letterlijk behandeld aan het begin is alleen gespecificeerd voor BREs. Met andere REs, YMMV.
  • @St é phaneChazelas Ik heb ' de specificatie voor de leidende asterisk niet gevonden . Is het ergens gedocumenteerd? Ik ' m gebruik ook gewoon grep (of grep -G).
  • @iBug, als je het antwoord zorgvuldiger leest, ' zal je opmerken wat (denk ik) je ' verwijzend is voor ast-open ' s grep -K die shell-patronen gebruikt (waarbij * komt overeen met een willekeurig aantal tekens).
  • @iBug, als je bedoelt dat * niet speciaal is wanneer het eerste teken van een BRE is, zie de POSIX-specificatie

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *