Obserwuję następujące zachowanie grep podczas jego uruchamiania pięć razy:

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$ 

Nie mogłem zrozumieć, dlaczego dwie ostatnie próby grep nie zwracają żadnego wyniku .

Odpowiedź

grep wzorce to wyrażenia regularne (inaczej regex, regexp, RE), podstawowe wyrażenia regularne (BRE), chyba że jedno z -E / -F / -P / -K / -X (tylko pierwsze dwa z nich są standardowe).

* to operator wyrażenia regularnego, który pasuje do 0 lub więcej poprzedzającego atomu . Na przykład d* pasuje do 0 lub więcej d s. W plikach BRE, na początku wzorca lub po

lub \( operatory regexp, pasuje tylko do literału * (jest również brane dosłownie wewnątrz [...] wyrażeń w nawiasach).

Zatem grep "*README.md*" pasuje do wierszy zawierających literał *, po którym następuje README, po którym następuje dowolny pojedynczy znak (operator . regexp), po którym następuje m, po którym następuje dowolna liczba d s. Ponieważ dowolna liczba zawiera 0, to „jest funkcjonalnie równoważne z grep "*README.m" (co nie miałoby znaczenia dla dopasowywanych wierszy, tylko z tym, co można dopasować w wierszu (co byłoby wyświetlane z opcją --color na przykład GNU grep)).

Na przykład , pasuje do tych 2 wierszy:

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

(^ s pokazujące, co w wierszu jest dopasowane za pomocą wyrażenia regularnego, które można było zobaczyć w przypadku --color)

Tutaj, wygląda na to, że mylisz wyrażenia regularne z wzorcami wieloznacznymi powłoki. Operator wieloznaczny *, który pasuje do 0 lub więcej znaków, można zapisać .* w wyrażeniach regularnych. Ale wykonanie:

grep ".*README\.md.*" 

znowu wyglądałoby tak samo, jak:

grep "README\.md" 

Jak grep szuka dopasowania wewnątrz linii, zamiast znaleźć wiersze, które dokładnie pasują do wzorca (dla których potrzebujesz -x).

Z ast-open grep, czyli również ksh93 „s grep wbudowany (nie zawsze jest wbudowany domyślnie i musisz go włączyć, umieszczając /opt/ast/bin przed $PATH), możesz użyć opcji -K dla grep, aby użyć symboli wieloznacznych powłoki (rozszerzone znaki ksh93). Więc z tym grep, możesz wykonać:

grep -K "README.md" 

lub

grep -xK "*README.md*" 

do dopasowania w wierszach zawierających README.md.

W tej samej implementacji dopasowywanie symboli wieloznacznych można również włączyć w rozszerzonym (), rozszerzony (-X) lub perlopodobny (-P) zwykły wyrażenia z operatorem (?K) (i \(?K\) w podstawowych wyrażeniach regularnych, które faktycznie łamią zgodność z POSIX, więc nie mógłbym na nim polegać można usunąć w przyszłej wersji). Możesz więc zrobić:

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

tam.

Z każdą nowoczesną implementacją grep, możesz również:

grep -F README.md 

W przypadku wyszukiwania ustalonego ciągu (gdzie . powyżej pasuje do literału . zamiast dowolnego znaku).

Komentarze

  • FWIW: Perl narzeka na * lub + na początku wyrażenia regularnego, podobnie jak grep -P
  • @ilkkachu , podobnie jak grep -E z kilkoma implementacjami. To * traktowane dosłownie, gdy na początku jest określone tylko dla BRE. W przypadku innych RE, YMMV.
  • @St é phaneChazelas nie ' nie znalazłem specyfikacji wiodącej gwiazdki . Czy jest to gdzieś udokumentowane? ' m używam też zwykłego grep (lub grep -G).
  • @iBug, jeśli uważniej przyjrzałeś się odpowiedzi, ' zauważysz, co (myślę) ' ponownie odnosi się do ast-open ' s grep -K, który używa wzorców powłoki (gdzie * pasuje do dowolnej liczby znaków).
  • @iBug, jeśli masz na myśli, że * nie jest specjalny, gdy pierwszy znak w BRE, zobacz specyfikacja POSIX

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *