Chcę wykluczyć plik ./test/main.cpp
z wyszukiwania.
Oto co widzę:
$ grep -r pattern --exclude=./test/main.cpp
./test/main.cpp:pattern
./lib/main.cpp:pattern
./src/main.cpp:pattern
Wiem, że możliwe jest uzyskanie żądanego wyniku za pomocą wielu poleceń w układzie potoków i filtrów, ale czy istnieje jakieś cytowanie / ucieczka, które pozwoli grep
zrozumieć, czego natywnie chcę?
command-line
grep
nobar
źródło
źródło
--exclude-dir
). Dlatego chciałbym, aby grep wykonał wykluczenie natywnie.Odpowiedzi:
grep
nie możesz tego zrobić dla pliku w jednym określonym katalogu, jeśli masz więcej plików o tej samej nazwie w różnych katalogach, zamiast tego użyj find:find . -type f \! -path './test/main.cpp' -exec grep pattern {} \+
źródło
\!
i\+
? Wydaje się, że działa dobrze bez ukośników.grep
nie można tego zrobić, użyjfind
zamiast tego” - idealnie.Nie sądzę, że jest to możliwe z GNU
grep
. Nie potrzebujesz jednak rur.Z
find
:Z
zsh
:(wyklucza ukryte pliki, a także, aby wykluczyć .git, .svn ...).
źródło
Mógłbym napisać książkę: „The Lost Art of
xargs
”. Dofind ... -exec … ';
uruchamia grep dla każdego pliku (ale wariant ze-exec … +
nie robi). Cóż, marnujemy obecnie cykle procesora, więc czemu nie, prawda? Ale jeśli problemem jest wydajność, pamięć i moc: użyj xargs:GNU
find
„s-print0
będzieNUL
-terminate jego produkcja ixargs
”-0
opcji wyróżnienia ten format jako wejście. Zapewnia to, że niezależnie od zabawnych znaków w pliku, potok nie zostanie pomylony. Ta-r
opcja zapewnia, że nie wystąpi błąd w przypadku, gdyfind
nic nie znajdzie.Uwaga: możesz teraz wykonywać następujące czynności:
GNU grep
-z
robi to samo, co xargs-0
.źródło
find -exec (cmd) {} +
działa tak samo jakxargs
ifind -exec (cmd) {} \;
działa tak samo jakxargs -n1
. Innymi słowy, twoje oświadczenie jest poprawne tylko wtedy, gdy\;
używana jest wersja.xargs
jest mniej wydajne niż używanie-exec … +
(choć nieznacznie). Żadna z odpowiedzi tutaj nawet nie wspomina-exec … \;
.-exec ... +
dodano w styczniu 2005. Tak, nie jestem nieaktualny ... w ogóle ... w ogóle.Jeśli masz
find
obsługę,-path
która została dodana do POSIX w 2008 roku, ale nadal jej brakuje w Solarisie:źródło
-path
nie jest POSIX?Dla przypomnienia, oto podejście, które wolę:
Trzymając
grep
na początku polecenia, myślę, że jest to nieco bardziej wyraźne - a ponadto nie wyłączagrep
podświetlania kolorów. W pewnym sensie użyciefind
w podstawianiu poleceń jest tylko sposobem na rozszerzenie / zastąpienie (ograniczonego) podzbiorugrep
funkcji wyszukiwania plików .Dla mnie
find -exec
składnia jest dość tajemnicza. Jedną ze złożonościfind -exec
jest (czasem) potrzeba ucieczki przed różnymi postaciami (zwłaszcza jeśli\;
jest używana pod Bash). Tylko w celu umieszczenia rzeczy w znanych kontekstach następujące dwa polecenia są w zasadzie równoważne:Jeśli chcesz wykluczyć podkatalogi , może być konieczne użycie znaku wieloznacznego. Nie do końca rozumiem tutaj schemat - mów o tajemniczych :
Jeszcze jedna uwaga na temat uogólnień
find
opartych na rozwiązaniach do użycia w skryptach :grep
Wiersz poleceń powinien zawierać opcję-H
/--with-filename
. W przeciwnym razie zmieni formatowanie wyjściowe pod warunkiem, że w wynikach wyszukiwania znajduje się tylko jedna nazwa plikufind
. Jest to godne uwagi, ponieważ nie wydaje się konieczne, jeśli używaszgrep
natywnego wyszukiwania plików (z-r
opcją).... Jeszcze lepiej jest dołączyć
/dev/null
jako pierwszy plik do przeszukania. To rozwiązuje dwa problemy:grep
pomyśli, że są dwa pliki i używa trybu wyjścia z wieloma plikami.grep
pomyśli, że jest jeden plik i nie zawiesi się, czekając na standardowe wejście.Ostateczna odpowiedź to:
źródło
find
w podstawianiu poleceń. Dzieje się tak, jeśli istnieją nazwy plików zawierające spacje lub inne znaki specjalne. Użyjfind -exec
, jest solidny i łatwy w użyciu.find -iname "*target*" -or -name 'exclude' -prune
. Cóż, to działa - przycięty katalog zostanie wyświetlony, ale nie zostanie przeszukany. Jeśli nie chcesz, aby była na liście, możesz dodać coś zbędnego! -name 'exclude'