Рекурсивно шукати папку, але виключати підпапку 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 .натомість, бачачи, що в ОП вже є GNU grep.
jw013

Особисто я маю shopt -s dotglobв Bash, тому *вже містить крапки-файли. -rприємно, але ackчи це теж за замовчуванням :)
ефемія

5

Вас може зацікавити ак . Він виконує рекурсивний пошук (та інші грепоподібні операції) та виключає каталоги, такі як .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
Я особисто роблю це за допомогою псевдоніма, щоб я міг обійти список виключень, якщо мені потрібно фактично шукати всередині цих папок, я можу просто використовувати голий греп, не вимикаючи / скасовуючи змінну. Це також дозволяє мені підтримувати список папок, які я можу легко розширити і автоматично додав до мого списку виключень без необхідності більше вводити текст.
dragon788

Це хороший підхід. Він також має перевагу в тому, що, якщо вам потрібно буде переключитися на папки, ви не забудете встановити змінну. (Не те, що мені коли-небудь потрібно було зірвати їх.) Але ТБХ в ці дні я використовую ag (ак клон) для цих речей ^^
brandizzi

0

Ось також дивне рішення:

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.