Jak rekurencyjnie grep
wszystkie katalogi i podkatalogi?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
nie działa dla mnie w Redhat Linux. Pojawia się błąd „brak dopasowania”.
Jak rekurencyjnie grep
wszystkie katalogi i podkatalogi?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
nie działa dla mnie w Redhat Linux. Pojawia się błąd „brak dopasowania”.
Odpowiedzi:
grep -r "texthere" .
Pierwszy parametr reprezentuje szukane wyrażenie regularne, a drugi katalog, który należy przeszukać. W takim przypadku .
oznacza bieżący katalog.
Uwaga: Działa to w przypadku GNU grep, a na niektórych platformach, takich jak Solaris, musisz w szczególności używać GNU grep zamiast implementacji starszej wersji. W przypadku Solaris jest to ggrep
polecenie.
AIX 5.3
.
Jeśli znasz rozszerzenie lub wzorzec pliku, który chcesz, inną metodą jest użycie --include
opcji:
grep -r --include "*.txt" texthere .
Możesz także wspomnieć o plikach do wykluczenia --exclude
.
Jeśli często przeszukujesz kod, Ag (The Silver Searcher) jest znacznie szybszą alternatywą dla grep, dostosowaną do wyszukiwania kodu. Na przykład jest domyślnie rekurencyjny i automatycznie ignoruje wymienione w nim pliki i katalogi .gitignore
, więc nie musisz ciągle przekazywać tych samych kłopotliwych opcji wykluczania grep lub find.
=
działa dobrze na Ubuntu. PS: to ma być przestarzałe miejsce, ale parser znaczników SO nie powiódł się.
grep
, a nie za Ag, po prostu wiesz :)
--include "*.txt" --include "*.TXT"
Również:
find ./ -type f -print0 | xargs -0 grep "foo"
ale grep -r
jest lepszą odpowiedzią.
find . -type f -exec grep "foo" '{}' \;
działa dobrze tam, gdzie jest obsługiwane.
find ./ -type f -print0 | xargs -0 grep "foo"
Teraz zawsze używam (nawet w systemie Windows z GoW - Gnu w systemie Windows ):
grep --include="*.xxx" -nRHI "my Text to grep" *
Obejmuje to następujące opcje:
--include=PATTERN
Powtarzaj w katalogach, szukając tylko pasujących plików
PATTERN
.
-n, --line-number
Poprzedź każdą linię wyjścia numerem linii w pliku wejściowym.
(Uwaga: phuclv dodaje w komentarzach , -n
co znacznie obniża wydajność , więc możesz chcieć pominąć tę opcję)
-R, -r, --recursive
Czytaj rekursywnie wszystkie pliki w każdym katalogu; jest to równoważne z
-d recurse
opcją.
-H, --with-filename
Wydrukuj nazwę pliku dla każdego dopasowania.
-I
Przetwarzaj plik binarny tak, jakby nie zawierał pasujących danych;
jest to równoważne z--binary-files=without-match
opcją.
I mogę dodać ' i
' ( -nRHIi
), jeśli chcę wyniki bez rozróżniania wielkości liter.
Mogę dostać:
/home/vonc/gitpoc/passenger/gitlist/github #grep --include="*.php" -nRHI "hidden" *
src/GitList/Application.php:43: 'git.hidden' => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
src/GitList/Provider/GitServiceProvider.php:21: $options['hidden'] = $app['git.hidden'];
tests/InterfaceTest.php:32: $options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
vendor/klaussilveira/gitter/lib/Gitter/Client.php:20: protected $hidden;
vendor/klaussilveira/gitter/lib/Gitter/Client.php:170: * Get hidden repository list
vendor/klaussilveira/gitter/lib/Gitter/Client.php:176: return $this->hidden;
...
-R
opcji) do folderów.
*
lub .
jest wzorem globalnym (interpretowanym przez powłokę): unix.stackexchange.com/a/64695/7490 . ' .
' wybierze również pliki kropkowe lub foldery kropkowe (jak .git/
)
grep -rnI
ale potem nauczyłem się, że -n
to znacznie obniża wydajność, więc używam go tylko wtedy, gdy jest naprawdę potrzebny i zwykle używam-rI
W systemach POSIX nie znajdziesz -r
parametru dla grep
i grep -rn "stuff" .
nie uruchomisz się, ale jeśli użyjesz find
polecenia, to:
find . -type f -exec grep -n "stuff" {} \; -print
Uzgodnione przez Solaris
i HP-UX
.
-exec
opcji - symbol {}
jest odniesieniem do nazwy pliku, która jest aktualnie znaleziona przez find
narzędzie (to znaczy, aby coś zrobić z nazwą pliku, którą znaleźliśmy), również -exec
opcja powinna być zakończona ;
symbolem (aby oznaczyć koniec poleceń exec), ale ponieważ to wszystko działający w powłoce, ten symbol powinien być poprzedzony znakiem ucieczki .. i na koniec -print
opcja pozwala find
drukować na ekranie znalezione nazwy plików.
**
Używanie grep -r
działa, ale może przesadzać, szczególnie w dużych folderach.
Dla bardziej praktycznego zastosowania, oto składnia, która używa składni globbing ( **
):
grep "texthere" **/*.txt
który greps tylko określone pliki z wybranym wzorem wzorca. Działa z obsługiwanymi powłokami, takimi jak Bash +4 lub zsh .
Aby aktywować tę funkcję, należy uruchomić: shopt -s globstar
.
Zobacz także: Jak znaleźć wszystkie pliki zawierające określony tekst w systemie Linux?
git grep
W przypadku projektów pod kontrolą wersji Git użyj:
git grep "pattern"
co jest znacznie szybsze.
ripgrep
W przypadku większych projektów najszybszym narzędziem grepping jest ripgrep
domyślnie które pliki greps są rekurencyjnie:
rg "pattern" .
Jest zbudowany na silniku wyrażeń regularnych Rust, który wykorzystuje skończone automaty, SIMD i agresywne optymalizacje dosłowne, aby wyszukiwanie było bardzo szybkie. Sprawdź szczegółową analizę tutaj .
Aby znaleźć nazwę files
z path
rekurencyjnie zawierającą dane string
polecenie poniżej, użyj dla UNIX
:
find . | xargs grep "searched-string"
dla Linux
:
grep -r "searched-string" .
znajdź plik na UNIX
serwerze
find . -type f -name file_name
znajdź plik na serwerze LINUX
find . -name file_name
Jeśli chcesz śledzić tylko rzeczywiste katalogi, a nie dowiązania symboliczne,
grep -r "thingToBeFound" directory
Jeśli chcesz podążać za dowiązaniami symbolicznymi oraz rzeczywistymi katalogami (uważaj na nieskończoną rekurencję),
grep -R "thing to be found" directory
Ponieważ próbujesz rekurencyjnie grep, przydatne mogą być również następujące opcje:
-H: outputs the filename with the line
-n: outputs the line number in the file
Więc jeśli chcesz znaleźć wszystkie pliki zawierające Dartha Vadera w bieżącym katalogu lub dowolnych podkatalogach i przechwycić nazwę pliku i numer linii, ale nie chcesz, aby rekursja podążała za dowiązaniami symbolicznymi, polecenie będzie
grep -rnH "Darth Vader" .
Jeśli chcesz znaleźć wszystkie wzmianki o słowie kot w katalogu
/home/adam/Desktop/TomAndJerry
i jesteś obecnie w katalogu
/home/adam/Desktop/WorldDominationPlot
i chcesz przechwycić nazwę pliku, ale nie numer wiersza żadnego wystąpienia ciągu „koty”, i chcesz, aby rekursja podążała za dowiązaniami symbolicznymi, jeśli je znajdzie, możesz wykonać jedną z następujących czynności
grep -RH "cats" ../TomAndJerry #relative directory
grep -RH "cats" /home/adam/Desktop/TomAndJerry #absolute directory
Źródło:
uruchamianie „grep --help”
Krótkie wprowadzenie do symbolicznych linków, dla każdego, kto czyta tę odpowiedź i jest zdezorientowany moim odniesieniem do nich: https://www.nixtutor.com/freebsd/understanding-symbolic-links/
ag to mój ulubiony sposób na zrobienie tego teraz github.com/ggreer/the_silver_searcher . Jest to w zasadzie to samo co potwierdzenie, ale z kilkoma dodatkowymi optymalizacjami.
Oto krótki punkt odniesienia. Wyczyszczam pamięć podręczną przed każdym testem (por. Https://askubuntu.com/questions/155768/how-do-i-clean-or-disable-the-memory-cache )
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time grep -r "hey ya" .
real 0m9.458s
user 0m0.368s
sys 0m3.788s
ryan@3G08:$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ack-grep "hey ya" .
real 0m6.296s
user 0m0.716s
sys 0m1.056s
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ag "hey ya" .
real 0m5.641s
user 0m0.356s
sys 0m3.444s
ryan@3G08$ time ag "hey ya" . #test without first clearing cache
real 0m0.154s
user 0m0.224s
sys 0m0.172s
To powinno działać:
grep -R "texthere" *
Jeśli szukasz określonej zawartości we wszystkich plikach ze struktury katalogów, możesz użyć, find
ponieważ jest bardziej jasne, co robisz:
find -type f -exec grep -l "texthere" {} +
Zauważ, że -l
(mała litera L) pokazuje nazwę pliku zawierającego tekst. Usuń go, jeśli zamiast tego chcesz wydrukować sam mecz. Lub użyj, -H
aby zebrać plik razem z dopasowaniem. Wszystkie inne alternatywy to:
find -type f -exec grep -Hn "texthere" {} +
Gdzie -n
drukuje numer linii.
find
rozwiązaniem zarówno uniknąć niepotrzebnego używania xargs
i używać +
zamiast \;
z -exec
, unikając w ten sposób mnóstwo niepotrzebnych startów procesowych. :-)
Ten działał w moim przypadku na mojej bieżącej maszynie (git bash na Windows 7):
find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"
Zawsze zapominam o -print0 i -0 dla ścieżek ze spacjami.
EDYCJA: Moim preferowanym narzędziem jest teraz ripgrep: https://github.com/BurntSushi/ripgrep/releases . Jest naprawdę szybki i ma lepsze ustawienia domyślne (takie jak domyślnie rekurencyjne). Taki sam przykład, jak w mojej oryginalnej odpowiedzi, ale przy użyciu ripgrep:rg -g "*.cs" "content pattern"
grep -r "texthere" .
(okres wypowiedzenia na końcu)
(^ kredyt: https://stackoverflow.com/a/1987928/1438029 )
Wyjaśnienie:
grep -r "texthere" /
(rekurencyjnie grepuj wszystkie katalogi i podkatalogi)
grep -r "texthere" .
(rekurencyjnie grep te katalogi i podkatalogi)
grep [options] PATTERN [FILE...]
[opcje]
-R, -r, --recursive
Odczytuj rekurencyjnie wszystkie pliki w każdym katalogu.
Jest to równoważne z opcją
-d recurse
lub--directories=recurse
.
$ grep --help
$ grep --help |grep recursive
-r, --recursive like --directories=recurse
-R, --dereference-recursive
ack
( http://beyondgrep.com/ )
W 2018 roku chcesz użyć ripgrep
lub the-silver-searcher
ponieważ są one znacznie szybsze niż alternatywy.
Oto katalog z 336 podkatalogami pierwszego poziomu:
% find . -maxdepth 1 -type d | wc -l
336
% time rg -w aggs -g '*.py'
...
rg -w aggs -g '*.py' 1.24s user 2.23s system 283% cpu 1.222 total
% time ag -w aggs -G '.*py$'
...
ag -w aggs -G '.*py$' 2.71s user 1.55s system 116% cpu 3.651 total
% time find ./ -type f -name '*.py' | xargs grep -w aggs
...
find ./ -type f -name '*.py' 1.34s user 5.68s system 32% cpu 21.329 total
xargs grep -w aggs 6.65s user 0.49s system 32% cpu 22.164 total
Na OSX, to instaluje ripgrep
: brew install ripgrep
. Instaluje silver-searcher
: brew install the_silver_searcher
.
rg
ma znaczną przewagę nad łączeniem rekurencyjnego polecenia grep od zera. Używanie rg
: rg foo
. Korzystanie z narzędzi UNIX: find . | xargs grep foo
. A jeśli któryś z twoich plików zawiera cytat, musisz go użyć find . -print0 | xargs -0 grep foo
. Czy pamiętasz, że jeśli używasz tego kilka razy w roku?
find . -type f -exec grep 'regex' {} +
co jest naprawdę łatwe do zapamiętania, jeśli używasz tych narzędzi z dowolną regularnością. Ale prawdopodobnie i tak powinieneś uruchomić ctags
lub etags
na drzewie źródłowym, jeśli chcesz często znajdować rzeczy.
Na moim serwerze IBM AIX (wersja systemu operacyjnego: AIX 5.2) użyj:
find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \;
spowoduje to wydrukowanie ścieżki / nazwy pliku i względnego numeru linii w pliku, takich jak:
./inc/xxxx_x.h
2865: / ** Opis: stringYouWannaFind * /
w każdym razie to działa dla mnie :)
Poniżej znajduje się polecenie wyszukiwania String
rekurencyjnie włączone Unix
i Linux
środowisko.
dla UNIX
polecenia jest:
find . -name "string to be searched" -exec grep "text" "{}" \;
dla Linux
polecenia jest:
grep -r "string to be searched" .
Aby uzyskać listę dostępnych flag:
grep --help
Zwraca wszystkie dopasowania tekstu regularnego w bieżącym katalogu z odpowiednim numerem wiersza:
grep -rn "texthere" .
Zwraca wszystkie dopasowania tekstu tekstowego , zaczynając od katalogu głównego, z odpowiednim numerem wiersza i ignorując wielkość liter:
grep -rni "texthere" /
flagi użyte tutaj:
-r
rekurencyjny -n
wypisz numer wiersza z wyjściem -i
zignoruj wielkość literMyślę, że to właśnie próbujesz napisać
grep myText $(find .)
i może to być coś innego, jeśli chcesz znaleźć grep hit
grep myText $(find .) | cut -d : -f 1 | sort | uniq
Zwróć uwagę, że find . -type f | xargs grep whatever
w przypadku zbyt wielu plików pasujących do funkcji find różne rodzaje rozwiązań będą napotykać błędy „Lista argumentów zbyt długa”.
Najlepszym rozwiązaniem jest, grep -r
ale jeśli to nie jest dostępne, użyj find . -type f -exec grep -H whatever {} \;
zamiast tego.
xargs
jest w szczególności obejściem problemu „Zbyt długa lista argumentów”.
find . -type f | xargs -L 100 grep whatever
xargs
jest znormalizowany, aby takie zachowanie było gotowe. „ xargs
Narzędzie ogranicza długość wiersza poleceń, tak aby przy wywołaniu wiersza poleceń połączone listy argumentów i środowiska ... nie przekraczały {ARG_MAX} -2048 bajtów.”
Oto funkcja rekurencyjna (przetestowana lekko za pomocą bash i sh), która przegląda wszystkie podfoldery danego folderu (1 USD) i używa grep
wyszukiwania podanego ciągu (3 USD) w podanych plikach (2 USD):
$ cat script.sh
#!/bin/sh
cd "$1"
loop () {
for i in *
do
if [ -d "$i" ]
then
# echo entering "$i"
cd "$i"
loop "$1" "$2"
fi
done
if [ -f "$1" ]
then
grep -l "$2" "$PWD/$1"
fi
cd ..
}
loop "$2" "$3"
Uruchomienie i przykładowe wyjście:
$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename