grep, ale tylko niektóre rozszerzenia plików


965

Pracuję nad pisaniem skryptów do grepniektórych katalogów, ale katalogi te zawierają różnego rodzaju typy plików.

Chcę greppo prostu .hi .cppteraz, ale może kilka innych w przyszłości.

Do tej pory mam:

{ grep -r -i CP_Image ~/path1/;

grep -r -i CP_Image ~/path2/;

grep -r -i CP_Image ~/path3/;

grep -r -i CP_Image ~/path4/;

grep -r -i CP_Image ~/path5/;} 

| mailx -s GREP email@domain.com

Czy ktoś może mi pokazać, jak teraz dodam tylko określone rozszerzenia plików?


13
Próbowałem grep -r -i CP_Image ~/path1/*.{h,cpp}?

8
Użyj The Silver Searcher : ag -i CP_Image ~/path[1-5] | mailx -s GREP email@domain.com. Zadanie wykonane.
Johnsyweb,


Użyj egrep (najprawdopodobniej jest wstępnie zainstalowany w systemie), a następnie możesz użyć wyrażenia regularnego.
Dogweather

8
Faceci GNU naprawdę się zawiedli, kiedy dodali, -raby grepwyszukiwać pliki, ponieważ łamie to mantrę UNIX dotyczącą posiadania narzędzi, które „robią jedną rzecz i robią to dobrze”. Istnieje doskonale dobre narzędzie do wyszukiwania plików o BARDZO oczywistej nazwie.
Ed Morton,

Odpowiedzi:


1351

Wystarczy użyć --includeparametru, jak poniżej:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP email@domain.com

to powinno robić, co chcesz.

Aby wziąć wyjaśnienie z odpowiedzi HoldOffHunger poniżej:

  • grep: Komenda

  • -r: rekurencyjnie

  • -i: ignoruj ​​wielkość liter

  • --include \*.cpp: wszystkie pliki * .cpp: C ++ (ucieczka z \ na wypadek, gdybyś miał katalog z gwiazdkami w nazwach plików)

  • ./: Rozpocznij od bieżącego katalogu.


123
Dla zapisu: -r (rekurencyjny) -i (ignore-case) --include (wyszukuj tylko pliki pasujące do wzorca pliku)
Luis

34
Może być dodatkowo zoptymalizowany dogrep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345]
zwolnienie

1
@Hong gdzie jest dokumentacja, że ​​-R jest dla dowiązań symbolicznych?
titus

8
Ten przykład wydaje się mieć wysoki wynik, ponieważ obejmuje tak szeroki zakres możliwości, ale odpowiedź podana poniżej grep -r --include = *. Txt 'searchterm' ./ naprawdę wyjaśnia istotę odpowiedzi
David Casper

10
dlaczego nie użyć podwójnych cudzysłowów zamiast odwrotnego ukośnika? np .:grep -r -i --include="*.h" --include="*.cpp" CP_Image
pambda

283

Niektóre z tych odpowiedzi wydawały się zbyt obszerne pod względem składni lub powodowały problemy na moim serwerze Debian. To działało idealnie dla mnie:

Rewolucja PHP: Jak grepować pliki w systemie Linux, ale tylko niektóre rozszerzenia plików?

Mianowicie:

grep -r --include=\*.txt 'searchterm' ./

... lub wersja bez rozróżniania wielkości liter ...

grep -r -i --include=\*.txt 'searchterm' ./
  • grep: Komenda

  • -r: rekurencyjnie

  • -i: ignoruj ​​wielkość liter

  • --include: all * .txt: pliki tekstowe (ucieczka z \ na wypadek, gdybyś miał katalog z gwiazdkami w nazwach plików)

  • 'searchterm': Czego szukać

  • ./: Rozpocznij od bieżącego katalogu.


7
Powinieneś uciec przed *użyciem \*.cpplub '*.cpp'. W przeciwnym razie nie da oczekiwanego rezultatu, gdy katalog roboczy zawiera niektóre *.txtpliki.
Melebius

@Melebius czy możesz wyjaśnić, dlaczego trzeba uciec - czy ma to coś wspólnego z wymienionymi wyżej rozszerzeniami CPP lub TXT? Czy użyłeś ich tylko jako przykładów?
Simon East

2
@ SimonEast Te rozszerzenia są używane w tym pytaniu i odpowiedzi, nic specjalnego inaczej. Prawdopodobnie działałby bez ucieczki podczas używania, --include=<pattern>ale ważne jest, aby uciec *z --include <pattern>(spacją zamiast =), co w innym przypadku wydaje się bardzo podobne.
Melebius

52
grep -rnw "some thing to grep" --include=*.{module,inc,php,js,css,html,htm} ./

3
grep -rn „coś do grep” --include = *. {module, inc, c, h} *
ashish

3
Niezła odpowiedź. Czystsze niż przyjęte w IMO, ale należy dodać kryteria wyszukiwania, jak zauważył
@ashish

dlaczego --includeopcja jest za igłą, a nie z innymi opcjami?
vladkras

@vladkras, co masz na myśli igła? Czy to --jest
heretoinfinity

50

Co powiesz na:

find . -name '*.h' -o -name '*.cpp' -exec grep "CP_Image" {} \; -print

5
sugerowałbym pogrupowanie tych -nameargumentów. dziwne rzeczy mogą się zdarzyć, jeśli tego nie zrobisz. find . \( -name '*.h' -o -name '*.cpp' \) -exec grep "CP_Image" {} \; -print
nullrevolution,

użyj z dodatkowym „-type f”, aby zignorować wszystkie obiekty katalogu, zainteresowane tylko plikami.
kensai

1
Używałem tej metody od lat i działa, ale jest DUŻO wolniejsza niż rekurencyjny grep, ponieważ exec find'a tworzy osobny proces grep dla każdego pliku do przeszukania.
beaudet

Adresowanie komentarza @ beaudet findmoże opcjonalnie wiązać argumenty, ograniczając wywoływanie wywoływanego procesu do minimum. find . \( -name \*.h -o -name \*.cpp \) -exec grep -H CP_Image {} + Jest to sugerowane, ale nie podkreślone w odpowiedzi @ fedorqui poniżej, i jest to godna uwagi poprawa. -HArgument grep tutaj jest przydatna, gdy tylko znaleźć identyfikuje pojedynczy plik pasujący. Może to wyeliminować użycie -printw odpowiedzi. Jeśli całkowita lista plików jest wystarczająco mała, {path1,path2}/**/*.{cpp,h}może być zalecane użycie globu powłoki rekurencyjnej (np. ).
Malcolm,

19

Na serwerach HP i Sun nie ma opcji -r, w ten sposób działało dla mnie na moim serwerze HP

find . -name "*.c" | xargs grep -i "my great text"

-i służy do wyszukiwania łańcucha bez rozróżniania wielkości liter


1
Natknąłem się na kilka serwerów dla firm hostingowych, które nie mają opcji --include dostępnej dla fgrep i jest to wiersz poleceń, którego używam w takich przypadkach.
Borgboy,

Opcja --include nie jest również dostępna podczas korzystania z Git dla Windows (MinGW / MSys).
Darren Lewis,

@DarrenLewis dostępny w Git Bash dla Windows. Ale, co dziwne, dodaje kolorowe aliasy, takie jak grep, llale go nie dodaje --color=auto.
Xeverous

To powinna być zaakceptowana odpowiedź na kompletność, przenośność i zwięzłość!
Grant Foster

12

Ponieważ jest to kwestia wyszukiwania plików, użyjmy find!

Korzystanie GNU znaleźć można skorzystać z -regexopcji, aby znaleźć te pliki w drzewie katalogów, których rozszerzenie jest albo .halbo .cpp:

find -type f -regex ".*\.\(h\|cpp\)"
#            ^^^^^^^^^^^^^^^^^^^^^^^

Następnie wystarczy wykonać grepkażdy z jego wyników:

find -type f -regex ".*\.\(h\|cpp\)" -exec grep "your pattern" {} +

Jeśli nie masz takiej dystrybucji znaleziska, musisz zastosować podejście takie jak Amir Afghani , używając -oopcji konkatenacji opcji ( nazwa kończy się na .hlub na.cpp ):

find -type f \( -name '*.h' -o -name '*.cpp' \) -exec grep "your pattern" {} +
#            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A jeśli naprawdę chcesz użyć grep, postępuj zgodnie ze wskazaną składnią --include:

grep "your pattern" -r --include=*.{cpp,h}
#                      ^^^^^^^^^^^^^^^^^^^


3

ag (srebrny wyszukiwarka) ma na to dość prostą składnię

       -G --file-search-regex PATTERN
          Only search files whose names match PATTERN.

więc

ag -G *.h -G *.cpp CP_Image <path>

używając ag 2.2.0, musiałem umieścić moje flagi na końcu:ag _string_to_find_ -G _filename_regex_
ryanrain

3

Poniższa odpowiedź jest dobra:

grep -r -i --include \*.h --include \*.cpp CP_Image ~/path[12345] | mailx -s GREP email@domain.com

Ale można zaktualizować do:

grep -r -i --include \*.{h,cpp} CP_Image ~/path[12345] | mailx -s GREP email@domain.com

Co może być prostsze.


1

Powinien napisać „-exec grep” dla każdego „-o -name”

find . -name '*.h' -exec grep -Hn "CP_Image" {} \; -o -name '*.cpp' -exec grep -Hn "CP_Image" {} \;

Lub pogrupuj je według ()

find . \( -name '*.h' -o -name '*.cpp' \) -exec grep -Hn "CP_Image" {} \;

opcja „-Hn” pokazuje nazwę pliku i linię.


1

Wiem, że to pytanie jest trochę przestarzałe, ale chciałbym udostępnić metodę, której zwykle używam do znajdowania plików .c i .h :

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -H "#include"

lub jeśli potrzebujesz również numeru linii:

tree -if | grep \\.[ch]\\b | xargs -n 1 grep -nH "#include"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.