Kiedy chcę grepować wszystkie pliki html w jakimś katalogu, wykonuję następujące czynności
grep --include="*.html" pattern -R /some/path
co działa dobrze. Problem w tym, jak grepować wszystkie pliki html, htm, php w jakimś katalogu?
Z tego Użyj grep --exclude / - include składnię, aby nie przeszukiwać niektórych plików , wydaje się, że mogę wykonać następujące czynności
grep --include="*.{html,php,htm}" pattern -R /some/path
Ale niestety to nie zadziała dla mnie.
FYI, moja wersja grep to 2.5.1.
xargs
. To jest również warto szybki odczyt. HTH.*
nadal podlega globbingowi jako część tokenu, w którym jest osadzony , po prostu zdarza się , że w tym przypadku nie pasuje do niczego, ponieważ pasowałyby tylko pliki o dosłownej nazwie podobnej--include=foo.html
. Aby być bezpiecznym, zacytuj*
(który możesz zrobić indywidualnie\*
). Jako dodatkowy bonus sprawia to wizualnie wyraźniejsze, że to nie powłoka powinna wykonywać globbing w tym przypadku.find
rozwiązanie: używanie-exec grep "pattern" {} +
zamiast| xargs grep "pattern"
jest bardziej niezawodne (obsługuje na przykład nazwy plików ze spacjami), a także bardziej wydajne.Korzystanie
{html,php,htm}
może pracować tylko jako rozszerzenie usztywniającym , który jest nietypowa (nie POSIX) cechąbash
,ksh
izsh
.Innymi słowy: nie próbuj używać go w skrypcie, który jest przeznaczony
/bin/sh
- w takim przypadku użyj jawnych wielu--include
argumentów.grep
sama nie rozumie{...}
notacji.Aby interpretacja nawiasów została rozpoznana, musi to być niecytowany (część) token w wierszu poleceń.
Rozwinięcie nawiasów klamrowych rozszerza się do wielu argumentów , więc w omawianym przypadku
grep
kończy się wyświetleniem wielu--include=...
opcji, tak jakbyś przeszedł je indywidualnie.Wyniki rozwijania nawiasów klamrowych podlegają globalizacji (rozwijaniu nazw plików) , co ma pułapki :
Każdą otrzymaną argument można dodatkowo rozszerzyć do dopasowania nazwami jeśli zdarzy się, że zawiera nienotowanych metaznaki plików takich jak
*
.Chociaż jest to mało prawdopodobne w przypadku tokenów, takich jak
--include=*.html
(np. Musiałbyś mieć plik o dosłownie nazwie podobnej--include=foo.html
do czegoś, co ma pasować), warto o tym ogólnie pamiętać.Jeśli
nullglob
opcja powłoki jest włączona (shopt -s nullglob
) i globbing nie pasuje do niczego , argument zostanie odrzucony .Dlatego, aby uzyskać w pełni solidne rozwiązanie , użyj następujących elementów:
'--include=*.'
jest traktowany jako literał , ponieważ występuje w pojedynczym cudzysłowie ; zapobiega to nieumyślnej interpretacji*
jako globbing postaci.{html,php,htm}
The - konieczności - niecytowany rozszerzalności usztywniającym [1] , rozszerza się 3 argumentów, które ze względu na{...}
następujące bezpośrednio po'...'
żeton , zawierających ten symbol.Dlatego po usunięciu cytatu przez powłokę, następujące 3 dosłowne argumenty są ostatecznie przekazywane do
grep
:--include=*.html
--include=*.php
--include=*.htm
[1] Dokładniej, tylko te części rozwinięcia nawiasów klamrowych, które mają znaczenie dla składni , muszą być niecytowane, elementy listy mogą nadal być cytowane indywidualnie i muszą być, jeśli zawierają globbing metaznaki, które mogą skutkować niepożądanym globowaniem po rozwinięciu nawiasów; chociaż nie jest to konieczne w tym przypadku, powyższe można zapisać jako
'--include=*.'{'html','php','htm'}
źródło
bash
na każdej platformie, na którejbash
działa.Spróbuj usunąć podwójne cudzysłowy
źródło
grep --include=\*.{html,php,htm} pattern -R /some/path
. U mnie to zadziałało.czy to nie działa?
źródło
Spróbuj tego. -r przeprowadzi wyszukiwanie rekurencyjne. -s pominie błędy nie znalezionych plików. -n pokaże numer wiersza pliku, w którym znajduje się wzorzec.
źródło
-I
do standardowego zestawu. Pomija pliki binarne (które prawie nigdy nie są przeszukiwane), co zwiększa wydajność. Potem idziemygrep -rIns ...
co ładnie gra akustycznie :)Działa w tym samym celu, ale bez
--include
opcji. Działa również na grep 2.5.1.źródło
Używaj
grep
zfind
poleceniemMożesz użyć
-regex
i-regextype
opcji.źródło