Рекурсивно искать папку, но исключать подпапку SVN


10

Я хочу найти все вхождения fooв большой файловой системе, поддерживаемой SVN, но я не хочу сопоставлять что-либо содержащееся в каком-либо .svnкаталоге.

Я получаю немедленные совпадения, когда я делаю, grep -l -e 'foo' *но когда я пытаюсь исключить каталоги SVN с grep -l -e 'foo' --exclude-dir=".svn"помощью команды просто зависает.

Что я делаю неправильно?

Ответы:


11

--exclude-dirне вытесняет необходимость перечислять файлы в командной строке. Вы "зависаете", потому что grepждете стандартного ввода.

grep -l -e 'foo' --exclude-dir = ". svn" *

Попробуйте использовать ack , который исключает .svnи похожие папки (и имеет много других функций) по умолчанию.


2
Очистить, если вы измените *на ., если есть другие скрытые папки, которые следует искать.
Кевин

или, возможно, вы хотите использовать --recursive .вместо этого, видя, как OP уже имеет GNU grep.
jw013

Лично у меня shopt -s dotglobв Bash, так что *уже есть дот-файлы. -rэто хорошо, но ackделает это по умолчанию тоже :)
ephemient

5

Вы можете быть заинтересованы в АСК . Он выполняет рекурсивный поиск (и другие подобные grep операции) и по умолчанию исключает такие каталоги, как .svn или .git .


В качестве продолжения этого я сейчас использую ag, что похоже, но быстрее.
WhyNotHugo

2

grep --exclude-dir...Решение должно быть хорошо, но только , чтобы показать другой путь, вы можете сделать это с помощью find«s -prune:

find -name .svn -prune -o -type f -exec grep -l "$pattern" {} +

Если вы хотите выполнить что-то дальше, findлучше, чем просто grep -r:

find -name .svn -prune -o -type f -exec grep -q "$pattern" {} \; -exec ./process {} \;

1

Если вы не хотите выполнять поиск в таких каталогах, как .svn когда-либо, вы можете установить $GREP_OPTIONSпеременную, чтобы исключить ее, как показано ниже:

export GREP_OPTIONS="--exclude-dir=\*/.svn/\*"

Просто добавьте эту строку к себе, .bashrcи ваши рекурсивные команды больше не будут входить в .svnкаталоги. Конечно, он может быть настолько богатым, насколько вы захотите:

export GREP_OPTIONS="--exclude-dir=\*/.svn/\* --exclude-dir=\*/.hg/\* --exclude-dir=\*/.git/\* --exclude=\*~"

1
Я лично делаю это с использованием псевдонима, чтобы я мог обойти список исключений, если мне нужно на самом деле искать внутри этих папок, я могу просто использовать чистый grep без необходимости сбрасывать / обнулять переменную. Это также позволяет мне вести список папок, которые я могу легко развернуть и автоматически добавить в список исключений без необходимости больше печатать.
dragon788

Это хороший подход. Он также имеет то преимущество, что если вам нужно выполнить поиск в папках, вы не забудете установить переменную. (Не то, чтобы я когда-либо нуждался в их grep.) Но в наши дни
TBH

0

Вот и решение awk:

find . | awk '$0 !~ /.svn/{print}' | awk '/foo/{print}'

По сути, из всех файлов удалите те, которые соответствуют /.svn/, а затем из них выведите только те, которые соответствуют / foo /. Мне также нравится это решение, так как вы можете легко использовать результаты с помощью ls. Например, вы можете использовать

ls -tl $(find . | awk '$0 !~ /.svn/{print}' | awk '/foo/{print}')

чтобы увидеть список, отсортированный по дате изменения. Также хорошо иметь полный путь к результатам, если вы хотите что-то с ними сделать (открыть их, выполнить и т. Д.)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.