Po prostu wpisz „man grep”, a zobaczysz opcje --exclude i --exclude-dir wymienione tutaj - z nagłówka tego pytania,
zakładam
34
Jeśli szukasz kodu w repozytorium git i node_modulesjest w twoim .gitignore, git grep "STUFF"jest to najłatwiejszy sposób. git grepprzeszukuje śledzone pliki w działającym drzewie, ignorując wszystko od.gitignore
0xcaff
2
Przykład dla węzła: grep -R --exclude-dir={node_modules,bower_components} "MyString" | cut -c1-"$COLUMNS"- ponadto możesz zawsze aliasować to w powłoce na „nodegrep” lub cokolwiek i użyć argumentu polecenia jako ciągu wejściowego.
bshea
Odpowiedzi:
394
ROZWIĄZANIE 1 (połącz findi grep)
Celem tego rozwiązania nie jest poradzenie sobie z grepwydajnością, ale pokazanie rozwiązania przenośnego: powinno również działać z busybox lub wersją GNU starszą niż 2.5.
Znasz już to rozwiązanie, ale dodaję je, ponieważ jest to najnowsze i wydajne rozwiązanie. Uwaga: jest to mniej przenośne rozwiązanie, ale bardziej czytelne dla człowieka.
Aby wykluczyć wiele katalogów, użyj --exclude-dirjako:
--exclude-dir={node_modules,dir1,dir2,dir3}
ROZWIĄZANIE 3 (Ag)
Jeśli często przeszukujesz kod, Ag (The Silver Searcher) jest znacznie szybszą alternatywą dla grep, dostosowaną do wyszukiwania kodu. Na przykład automatycznie ignoruje pliki i katalogi wymienione w .gitignore, więc nie musisz ciągle przekazywać tych samych uciążliwych opcji wykluczania do greplub find.
ta kombinacja wyszukuje szybciej niż --exclude-dir=diri pokazuje wyniki z kolorami - łatwa do odczytania
Maxim Yefremov
27
„ta kombinacja” find ... -execnie jest szybsza niż grep --exclude-dirdla mnie. Ogromną zaletą do grep (około pięć razy szybciej z 26k + plików, odfiltrowane od 38 tys + na HDD), chyba wymienić \;z +za find / exec kombi. Wtedy grep jest „tylko” o około 30% szybszy. Składnia grep jest również czytelna dla człowieka :).
Kjell Andreassen
Zgoda, ponieważ jest to oczywiste. Niektóre busyboxy nie mają polecenia GREP.
hornetbzz
10
zauważając również, że można wykluczyć wielokrotność za pomocą--exclude-dir={dir1,dir2}
suh
4
Nie jestem wcale zaskoczony, że node_modulesjest to kanoniczny przykład.
@Manocho: Jeśli uważasz, że ackjest świetny, wypróbuj The Silver Searcher i zobacz wzrost prędkości!
Johnsyweb
30
Składnia dla niecierpliwych: --exclude-dir=dirużywa grepwzorców wyrażeń regularnych, a nie globowania plików powłoki. Wzory działają na ścieżkach względem bieżącego katalogu. Więc użyć wzoru --exclude-dir=dir, nie --exclude-dir="/root/dir/*".
tanius
15
Jeśli chcesz wykluczyć z wyszukiwania wiele katalogów, czy jest lepsza opcja niż użycie $ grep -r --exclude-dir=dir1 --exclude-dir=dir2 "string" /path/to/search/dir:?
Darszan Chaudhary
4
Prawdopodobnie spędziłem na tym zbyt dużo czasu niż jakikolwiek rozsądny człowiek, ale nie mogę przez całe życie wymyślić, jak wykluczyć podkatalog z wyszukiwania - grep -r --exclude-dir=public keyword .działa, ale grep -r --exclude-dir='public/dist' keyword .nie działa. Próbowałem dodać symbole zastępcze, znaki ucieczki itp., Ale nic nie pomaga.
dkobozev
72
Wyklucz wiele takich katalogów:grep -r "Request" . --exclude-dir={node_modules,git,build}
maverick97
77
Jeśli chcesz wykluczyć wiele katalogów :
„r” dla rekurencyjnego, „l”, aby wydrukować tylko nazwy plików zawierających dopasowania, a „i”, aby zignorować rozróżnienie wielkości liter:
Przykład: Chcę znaleźć pliki zawierające słowo „cześć”. Chcę wyszukiwać we wszystkich moich katalogach linux oprócz katalogu proc, katalogu rozruchowego, katalogu sys i katalogu głównego :
UWAGA: nie dodawaj spacji po przecinkach w{dir1,dir2,dir3}
skplunkerin
Dzięki, przydatne, gdy grep'ing przez obszar roboczy SVN:grep -Irsn --exclude-dir=.svn 'foo' .
RAM237
1
Możesz po prostu podać tę --exclude-diropcję wiele razy.
Walf
44
Ta składnia
--exclude-dir={dir1,dir2}
jest rozszerzany przez powłokę (np. Bash), a nie przez grep, do tego:
--exclude-dir=dir1 --exclude-dir=dir2
Cytowanie uniemożliwi rozwinięcie go przez powłokę, więc to nie zadziała:
--exclude-dir='{dir1,dir2}' <-- this won't work
Wzory używane z --exclude-dirsą tego samego rodzaju wzorcami opisanymi na stronie podręcznika dla --excludeopcji:
--exclude=GLOB
Skip files whose base name matches GLOB (using wildcard matching).
A file-name glob can use *, ?, and [...] as wildcards, and \ to
quote a wildcard or backslash character literally.
Powłoka zazwyczaj będzie próbowała rozwinąć taki wzór, więc aby tego uniknąć, powinieneś go zacytować:
--exclude-dir='dir?'
Możesz używać nawiasów klamrowych i cytowanych razem wykluczać wzory w następujący sposób:
--exclude-dir={'dir?','dir??'}
Wzór może obejmować wiele segmentów ścieżki:
--exclude-dir='some*/?lse'
Wykluczałoby to katalog podobny do topdir/something/else.
grepmoże być używany w połączeniu z -r(rekurencyjne), i(ignoruj wielkość liter) i -o(drukuje tylko pasującą część linii). Aby wykluczyć filesużycie --excludei aby wykluczyć użycie katalogów --exclude-dir.
Jego opis sprawia, że brzmi o wiele bardziej skomplikowane niż jest w rzeczywistości. Łatwiej to zilustrować prostym przykładem.
Przykład:
Załóżmy, że szukam bieżącego projektu dla wszystkich miejsc, w których jawnie ustawiam wartość debuggerciągu podczas sesji debugowania, a teraz chcę przejrzeć / usunąć.
Piszę skrypt o nazwie findDebugger.shi używam grepdo znalezienia wszystkich wystąpień. Jednak:
W przypadku wykluczeń plików - chciałbym się upewnić, że .eslintrczostanie zignorowany (w rzeczywistości jest to reguła podszywania się, debuggerdlatego należy go wykluczyć). Podobnie nie chcę, aby mój skrypt zawierał odwołania w jakichkolwiek wynikach.
Wyłączenia katalogów - chcę wykluczyć, node_modulesponieważ zawiera wiele bibliotek, które zawierają odwołania debuggeri nie jestem zainteresowany tymi wynikami. Chciałbym też pominąć .ideai .gitukryć katalogi, ponieważ nie dbam też o te lokalizacje wyszukiwania i chcę zachować skuteczność wyszukiwania.
Oto wynik - tworzę skrypt o nazwie findDebugger.sh:
W niektórych przypadkach niezbyt dobre rozwiązanie. Na przykład: Jeśli katalog „node_modules” jest ogromny i zawiera wiele fałszywie pozytywnych dopasowań (stąd potrzeba odfiltrowania katalogu), to pierwszy grep marnuje dużo czasu na przeszukiwanie podkatalogu, a NASTĘPNIE drugi filtr grep mecze. Szybciej jest wykluczyć node_modules w pierwszym grep.
GuruM,
2
nie dbam o powolność, mogę spojrzeć na komendę i wiedzieć, co robi
Funkodebat
1
To samo dotyczy komentarza Guru. Grep /varzawiesza się, gdy uderza /var/runw moim przypadku. Dlatego przede wszystkim chcę uniknąć katalogu.
jww
3
--exclude-dirjest najlepszym rozwiązaniem od 2016 r.
Omar Tariq,
10
Jeśli szukasz kodu w repozytorium git i node_modulesjest w twoim .gitignore, możesz użyć git grep. git grepprzeszukuje śledzone pliki w działającym drzewie, ignorując wszystko od.gitignore
Podano tu wiele poprawnych odpowiedzi, ale dodaję tę, aby podkreślić jeden punkt, który spowodował, że niektóre pośpieszne próby zawiodły wcześniej: exclude-dirprzyjmuje wzorzec , a nie ścieżkę do katalogu.
Powiedz, że twoje wyszukiwanie to:
grep -r myobject
Zauważysz, że wyniki są zaśmiecone wynikami z src/other/objects-folder. To polecenie nie da zamierzonego wyniku:
I możesz się zastanawiać, dlaczego exclude-dirnie działa! Aby faktycznie wykluczyć wyniki z objects-folder, po prostu zrób to:
grep -r myobject --exclude-dir=objects-folder
Innymi słowy, po prostu użyj nazwy folderu , a nie ścieżki. Oczywiste, kiedy już to wiesz.
Ze strony podręcznika:
--exclude-dir = GLOB
Pomiń dowolny katalog wiersza poleceń z sufiksem nazwy zgodnym ze wzorcem GLOB. Podczas wyszukiwania rekurencyjnego pomiń dowolny podkatalog, którego podstawowa nazwa pasuje do GLOB. Zignoruj zbędne ukośniki końcowe w GLOB.
node_modules
jest w twoim.gitignore
,git grep "STUFF"
jest to najłatwiejszy sposób.git grep
przeszukuje śledzone pliki w działającym drzewie, ignorując wszystko od.gitignore
grep -R --exclude-dir={node_modules,bower_components} "MyString" | cut -c1-"$COLUMNS"
- ponadto możesz zawsze aliasować to w powłoce na „nodegrep” lub cokolwiek i użyć argumentu polecenia jako ciągu wejściowego.Odpowiedzi:
ROZWIĄZANIE 1 (połącz
find
igrep
)Celem tego rozwiązania nie jest poradzenie sobie z
grep
wydajnością, ale pokazanie rozwiązania przenośnego: powinno również działać z busybox lub wersją GNU starszą niż 2.5.Użyj
find
, aby wykluczyć katalogi foo i bar:Następnie połącz
find
i nierekurencyjne użyciegrep
jako rozwiązania przenośnego:ROZWIĄZANIE 2 (rekurencyjne użycie
grep
):Znasz już to rozwiązanie, ale dodaję je, ponieważ jest to najnowsze i wydajne rozwiązanie. Uwaga: jest to mniej przenośne rozwiązanie, ale bardziej czytelne dla człowieka.
Aby wykluczyć wiele katalogów, użyj
--exclude-dir
jako:--exclude-dir={node_modules,dir1,dir2,dir3}
ROZWIĄZANIE 3 (Ag)
Jeśli często przeszukujesz kod, Ag (The Silver Searcher) jest znacznie szybszą alternatywą dla grep, dostosowaną do wyszukiwania kodu. Na przykład automatycznie ignoruje pliki i katalogi wymienione w
.gitignore
, więc nie musisz ciągle przekazywać tych samych uciążliwych opcji wykluczania dogrep
lubfind
.źródło
--exclude-dir=dir
i pokazuje wyniki z kolorami - łatwa do odczytaniafind ... -exec
nie jest szybsza niżgrep --exclude-dir
dla mnie. Ogromną zaletą do grep (około pięć razy szybciej z 26k + plików, odfiltrowane od 38 tys + na HDD), chyba wymienić\;
z+
za find / exec kombi. Wtedy grep jest „tylko” o około 30% szybszy. Składnia grep jest również czytelna dla człowieka :).--exclude-dir={dir1,dir2}
node_modules
jest to kanoniczny przykład.Najnowsze wersje GNU Grep (> = 2.5.2 ) zapewniają:
co wyklucza katalogi pasujące do wzorca
dir
z rekurencyjnych wyszukiwań katalogów.Możesz więc zrobić:
Aby uzyskać więcej informacji na temat składni i użycia, zobacz
W przypadku starszych GNU Greps i POSIX Grep używaj,
find
jak sugerowano w innych odpowiedziach.Lub po prostu użyj
ack
( Edycja : lub Srebrny Poszukiwacz ) i gotowe!źródło
ack
jest świetny, wypróbuj The Silver Searcher i zobacz wzrost prędkości!--exclude-dir=dir
używagrep
wzorców wyrażeń regularnych, a nie globowania plików powłoki. Wzory działają na ścieżkach względem bieżącego katalogu. Więc użyć wzoru--exclude-dir=dir
, nie--exclude-dir="/root/dir/*"
.$ grep -r --exclude-dir=dir1 --exclude-dir=dir2 "string" /path/to/search/dir
:?grep -r --exclude-dir=public keyword .
działa, alegrep -r --exclude-dir='public/dist' keyword .
nie działa. Próbowałem dodać symbole zastępcze, znaki ucieczki itp., Ale nic nie pomaga.grep -r "Request" . --exclude-dir={node_modules,git,build}
Jeśli chcesz wykluczyć wiele katalogów :
„r” dla rekurencyjnego, „l”, aby wydrukować tylko nazwy plików zawierających dopasowania, a „i”, aby zignorować rozróżnienie wielkości liter:
Przykład: Chcę znaleźć pliki zawierające słowo „cześć”. Chcę wyszukiwać we wszystkich moich katalogach linux oprócz katalogu proc, katalogu rozruchowego, katalogu sys i katalogu głównego :
Uwaga: powyższy przykład musi być rootem
Uwaga 2 (zgodnie z @skplunkerin): nie dodawaj spacji po przecinkach
{dir1,dir2,dir3}
źródło
{dir1,dir2,dir3}
grep -Irsn --exclude-dir=.svn 'foo' .
--exclude-dir
opcję wiele razy.Ta składnia
jest rozszerzany przez powłokę (np. Bash), a nie przez
grep
, do tego:Cytowanie uniemożliwi rozwinięcie go przez powłokę, więc to nie zadziała:
Wzory używane z
--exclude-dir
są tego samego rodzaju wzorcami opisanymi na stronie podręcznika dla--exclude
opcji:Powłoka zazwyczaj będzie próbowała rozwinąć taki wzór, więc aby tego uniknąć, powinieneś go zacytować:
Możesz używać nawiasów klamrowych i cytowanych razem wykluczać wzory w następujący sposób:
Wzór może obejmować wiele segmentów ścieżki:
Wykluczałoby to katalog podobny do
topdir/something/else
.źródło
Często używaj tego:
grep
może być używany w połączeniu z-r
(rekurencyjne),i
(ignoruj wielkość liter) i-o
(drukuje tylko pasującą część linii). Aby wykluczyćfiles
użycie--exclude
i aby wykluczyć użycie katalogów--exclude-dir
.Podsumowując, otrzymujesz coś takiego:
Jego opis sprawia, że brzmi o wiele bardziej skomplikowane niż jest w rzeczywistości. Łatwiej to zilustrować prostym przykładem.
Przykład:
Załóżmy, że szukam bieżącego projektu dla wszystkich miejsc, w których jawnie ustawiam wartość
debugger
ciągu podczas sesji debugowania, a teraz chcę przejrzeć / usunąć.Piszę skrypt o nazwie
findDebugger.sh
i używamgrep
do znalezienia wszystkich wystąpień. Jednak:W przypadku wykluczeń plików - chciałbym się upewnić, że
.eslintrc
zostanie zignorowany (w rzeczywistości jest to reguła podszywania się,debugger
dlatego należy go wykluczyć). Podobnie nie chcę, aby mój skrypt zawierał odwołania w jakichkolwiek wynikach.Wyłączenia katalogów - chcę wykluczyć,
node_modules
ponieważ zawiera wiele bibliotek, które zawierają odwołaniadebugger
i nie jestem zainteresowany tymi wynikami. Chciałbym też pominąć.idea
i.git
ukryć katalogi, ponieważ nie dbam też o te lokalizacje wyszukiwania i chcę zachować skuteczność wyszukiwania.Oto wynik - tworzę skrypt o nazwie
findDebugger.sh
:źródło
-R
(nie pamiętam, dlaczego teraz). Zwykle używam-r
. Okazuje się, że wielka wersja podąża za dowiązaniami symbolicznymi . TILMożesz spróbować czegoś takiego
grep -R search . | grep -v '^node_modules/.*'
źródło
/var
zawiesza się, gdy uderza/var/run
w moim przypadku. Dlatego przede wszystkim chcę uniknąć katalogu.--exclude-dir
jest najlepszym rozwiązaniem od 2016 r.Jeśli szukasz kodu w repozytorium git i
node_modules
jest w twoim.gitignore
, możesz użyćgit grep
.git grep
przeszukuje śledzone pliki w działającym drzewie, ignorując wszystko od.gitignore
źródło
Bardzo przydatne, szczególnie dla osób zajmujących się Node.js, w których chcemy uniknąć przeszukiwania „node_modules”:
źródło
Proste działające polecenie:
Powyżej szukam tekstu „creativecommons.org” w bieżącym katalogu „dspace” i wykluczam katalogi {log, assetstore}.
Gotowy.
źródło
Podano tu wiele poprawnych odpowiedzi, ale dodaję tę, aby podkreślić jeden punkt, który spowodował, że niektóre pośpieszne próby zawiodły wcześniej:
exclude-dir
przyjmuje wzorzec , a nie ścieżkę do katalogu.Powiedz, że twoje wyszukiwanie to:
Zauważysz, że wyniki są zaśmiecone wynikami z
src/other/objects-folder
. To polecenie nie da zamierzonego wyniku:I możesz się zastanawiać, dlaczego
exclude-dir
nie działa! Aby faktycznie wykluczyć wyniki zobjects-folder
, po prostu zrób to:Innymi słowy, po prostu użyj nazwy folderu , a nie ścieżki. Oczywiste, kiedy już to wiesz.
Ze strony podręcznika:
źródło
Ten działa dla mnie:
źródło
źródło
Prostszym sposobem byłoby filtrowanie wyników za pomocą „grep -v”.
grep -i needle -R * | grep -v node_modules
źródło