Szukam ciągu foo=
w plikach tekstowych w drzewie katalogów. Jest na wspólnej maszynie z Linuksem, mam powłokę bash:
grep -ircl "foo=" *
W katalogach znajduje się także wiele plików binarnych pasujących do „foo =”. Ponieważ te wyniki nie są istotne i spowalniają wyszukiwanie, chcę, aby grep pomijał wyszukiwanie tych plików (głównie obrazy JPEG i PNG). Jak mam to zrobić?
Wiem, że istnieją opcje --exclude=PATTERN
i --include=PATTERN
, ale jaki jest format wzoru? Strona man grep mówi:
--include=PATTERN Recurse in directories only searching file matching PATTERN.
--exclude=PATTERN Recurse in directories skip file matching PATTERN.
Wyszukiwanie w grep włącz , grep włącz wyklucz , grep wyklucz i warianty nie znalazły nic istotnego
Jeśli istnieje lepszy sposób na grepowanie tylko w niektórych plikach, jestem za tym; przeniesienie niepoprawnych plików nie jest opcją. Nie mogę przeszukiwać tylko niektórych katalogów (struktura katalogów to wielki bałagan, wszystko jest wszędzie). Ponadto nie mogę niczego zainstalować, więc muszę zrobić ze zwykłymi narzędziami (takimi jak grep lub sugerowane znalezisko ).
--exclude-dir=.svn
, aby grep w ogóle do nich nie wchodziłgrep -r --exclude-dir=var "pattern" .
Odpowiedzi:
Użyj składni globowania powłoki:
Składnia dla
--exclude
jest identyczna.Zauważ, że gwiazdę ucieka odwrotnym ukośnikiem, aby zapobiec jej rozszerzeniu przez powłokę (cytowanie jej, na przykład
--include="*.{cpp,h}"
, działałoby równie dobrze). W przeciwnym razie, jeśli w bieżącym katalogu roboczym byłyby jakieś pliki, które pasowałyby do wzorca, wiersz poleceń rozwinąłby się do czegoś takiegogrep pattern -r --include=foo.cpp --include=bar.h rootdir
, co przeszukiwałoby tylko pliki o nazwachfoo.cpp
ibar.h
, co prawdopodobnie nie jest tym, czego chciałeś.źródło
grep pattern -r --include="*.{cpp,h}" rootdir
grep pattern -r --include=foo.cpp --include=bar.h rootdir
, który przeszuka tylko pliki o nazwiefoo.cpp
lubbar.h
. Jeśli nie masz żadnych plików, które pasują do glob w bieżącym katalogu, powłoka przekazuje glob do grep, co poprawnie interpretuje.--exclude-dir
opcja. Obowiązują jednak te same zasady. Dopasowywana jest tylko nazwa pliku katalogu, a nie ścieżka.--include
wydaje się nie działać po--exclude
. Podejrzewam, że nie ma sensu nawet próbować, z wyjątkiem tego, że mamalias
grep z długą listą--exclude
i--exclude-dir
, której używam do wyszukiwania kodu, ignorowania bibliotek i zamiany plików i innych rzeczy. Miałem nadzieję, żegrep -r --exclude='*.foo' --include='*.bar'
to zadziała, więc mógłbym ograniczyć moje tylkoalias
do--include='*.bar'
, ale wydaje się, że ignoruje--include
i zawiera wszystko, co nie jest plikiem .foo. Zamiana kolejności--include
i--exclude
działa, ale niestety to nie pomaga w moim przypadkualias
.PATTERN
. Pół godziny nie mogę znaleźć żadnego opisu tego, na co tam czekająJeśli chcesz po prostu pominąć pliki binarne, proponuję spojrzeć na
-I
opcję (wielkie litery i). Ignoruje pliki binarne. Regularnie używam następującego polecenia:Przeszukuje rekurencyjnie, ignoruje pliki binarne i nie zagląda do ukrytych folderów Subversion pod kątem dowolnego wzoru. Mam alias jako „grepsvn” na moim pudełku w pracy.
źródło
--exclude-dir
nie jest dostępne wszędzie. moje pole RH w pracy z GNU grep 2.5.1 go nie ma.--exclude-dir
jest niedostępne? We wszystkich moich próbach--exclude
wydaje się nie pasować do rachunku.--exclude-dir="\.git"
. :-)Proszę spojrzeć na ack , który jest przeznaczony do dokładnie takich sytuacji. Twój przykład
odbywa się za pomocą ack as
ponieważ potwierdzenie nigdy nie przegląda plików binarnych, a opcja -r jest domyślnie włączona. A jeśli chcesz tylko pliki CPP i H, po prostu zrób
źródło
apt-get
w Ubuntu :)awk
grep 2.5.3 wprowadził parametr --exclude-dir, który będzie działał tak, jak chcesz.
Możesz także ustawić zmienną środowiskową: GREP_OPTIONS = "- exclude-dir = .svn"
Zaraz sekundy Andy'ego zagłosuj na ACK jednak, że jest to najlepsze.
źródło
Znalazłem to po długim czasie, możesz dodać wiele włączeń i wykluczeń, takich jak:
źródło
Sugerowane polecenie:
jest błędne koncepcyjnie, ponieważ --exclude działa na basenieame. Innymi słowy, pominie tylko .svn w bieżącym katalogu.
źródło
W grep 2.5.1 musisz dodać tę linię do profilu ~ / .bashrc lub ~ / .bash
źródło
Uważam, że wyjście grepping grep jest bardzo pomocne:
Chociaż tak naprawdę nie powstrzymuje go to od przeszukiwania plików binarnych.
źródło
grep -I
do pominięcia plików binarnych.Jeśli nie masz nic przeciwko używaniu
find
, podoba mi się jego-prune
funkcja:W pierwszym wierszu określasz katalog, który chcesz przeszukać.
.
(bieżący katalog) to na przykład poprawna ścieżka.Na 2. i 3. linii, użyj
"*.png"
,"*.gif"
,"*.jpg"
, i tak dalej. Użyj tyle-o -name "..." -prune
konstrukcji, ile masz wzorów.Na 4 linii, trzeba inny
-o
(określa ona „lub”find
), wzorce Ty chcesz, i trzeba albo-print
czy-print0
na końcu. Jeśli chcesz po prostu „wszystko inne”, która pozostaje po przycinanie*.gif
,*.png
itd obrazów, a następnie użyć-o -print0
i skończysz z 4 linii.Wreszcie w piątym wierszu jest potok, do
xargs
którego pobiera każdy z wynikowych plików i przechowuje je w zmiennejFILENAME
. Następnie przechodzigrep
do-IR
flagi,"pattern"
, a następnieFILENAME
rozszerza się przezxargs
stać, że lista nazw znaleźćfind
.W przypadku konkretnego pytania oświadczenie może wyglądać mniej więcej tak:
źródło
-false
natychmiast po każdej,-prune
więc zapomnienie użycia-print0
lub jakieśexec
polecenie nie spowoduje wydrukowania plików, które chcesz wykluczyć:-name "*.png" -prune -false -o name "*.gif -prune -false
...W CentOS 6.6 / Grep 2.6.3 muszę go używać w następujący sposób:
Zwróć uwagę na brak równych znaków „=” (inaczej
--include
,--exclude
,include-dir
i--exclude-dir
są ignorowane)źródło
git grep
Użyj,
git grep
który jest zoptymalizowany pod kątem wydajności i ma na celu wyszukiwanie w niektórych plikach.Domyślnie ignoruje pliki binarne i honoruje twoje
.gitignore
. Jeśli nie pracujesz ze strukturą Git, nadal możesz z niej korzystać, przechodząc--no-index
.Przykładowa składnia:
Aby uzyskać więcej przykładów, zobacz:
źródło
Oczywiście jestem dyletantem, ale oto jak wygląda mój ~ / .bash_profile:
Zauważ, że aby wykluczyć dwa katalogi, musiałem dwukrotnie użyć opcji --exclude-dir.
źródło
Spróbuj tego:
Założono tutaj: http://www.unix.com/shell-programming-scripting/42573-search-files-exclusion-binary-files.html
źródło
Jeśli wyszukujesz nierekurencyjnie, możesz użyć wzorców Glop, aby dopasować nazwy plików.
zawiera html i txt. Przeszukuje tylko bieżący katalog.
Aby wyszukać w podkatalogach:
W podkatalogach:
źródło
ripgrep
Jest to jedno z najszybszych narzędzi zaprojektowanych do rekurencyjnego przeszukiwania bieżącego katalogu. Jest napisany w języku Rust , zbudowanym na silniku regularnym Rust, aby uzyskać maksymalną wydajność. Sprawdź szczegółową analizę tutaj .
Możesz więc po prostu uruchomić:
Szanuje twoje
.gitignore
i automatycznie pomija ukryte pliki / katalogi i pliki binarne.Nadal możesz dostosowywać dołączanie lub wykluczanie plików i katalogów za pomocą
-g
/--glob
. Reguły.gitignore
globowania odpowiadają globom. Sprawdźman rg
pomoc.Aby uzyskać więcej przykładów, zobacz: Jak wykluczyć niektóre pliki niezgodne z niektórymi rozszerzeniami z grep?
W systemie macOS można zainstalować za pośrednictwem
brew install ripgrep
.źródło
znajdź i xargs są twoimi przyjaciółmi. Użyj ich do filtrowania listy plików zamiast grep's --exclude
Spróbuj czegoś takiego
Zaletą przyzwyczajenia się do tego jest to, że można go rozszerzyć na inne przypadki użycia, na przykład do zliczania linii we wszystkich plikach innych niż png:
Aby usunąć wszystkie pliki inne niż PNG:
itp.
Jak wskazano w komentarzach, jeśli niektóre pliki mogą mieć spacje w swoich nazwach, użyj
-print0
ixargs -0
zamiast.źródło
te skrypty nie rozwiązują całego problemu ... Spróbuj tego lepiej:
ten skrypt jest o wiele lepszy, ponieważ używa „prawdziwych” wyrażeń regularnych, aby uniknąć wyszukiwania katalogów. po prostu oddziel nazwy folderów lub plików za pomocą „\ |” na grep -v
ciesz się! znalezione na mojej powłoce linux! XD
źródło
Spójrz @ ten.
źródło
--binary-files=without-match
Opcja GNUgrep
dostaje to, aby pominąć pliki binarne. (Odpowiednik-I
przełącznika wymienionego gdzie indziej.)(Może to wymagać najnowszej wersji
grep
; przynajmniej 2.5.3.)źródło
nadaje się do pliku .alias tcsh:
Trochę mi zajęło ustalenie, że część {mm, m, h, cc, c} NIE powinna znajdować się w cudzysłowie. ~ Keith
źródło
Aby zignorować wszystkie wyniki binarne z grep
Część awk odfiltruje wszystkie wiersze pliku binarnego foo
źródło
Spróbuj tego:
--F
” pod currdir .. (lub połącz inny folder o nazwie „--F
”, tjdouble-minus-F
.#> grep -i --exclude-dir="\-\-F" "pattern" *
źródło