Как я могу исключить каталоги из grep -R?

Я хочу пройти все подкаталоги, за исключением каталога node_modules.

Ответ 1

РЕШЕНИЕ 1 (комбинировать find и grep)

Цель этого решения заключается не в том, чтобы иметь дело с эффективностью grep а в том, чтобы показать портативное решение: также следует работать с версией busybox или GNU старше 2.5.

Используйте find, для исключения каталогов foo и bar:

find /dir \( -name foo -prune \) -o \( -name bar -prune \) -o -name "*.sh" -print

Затем комбинируйте find и нерекурсивное использование grep в качестве переносного решения:

find /dir \( -name node_modules -prune \) -o -name "*.sh" -exec grep --color -Hn "your text to find" {} 2>/dev/null \;

РЕШЕНИЕ 2 (рекурсивное использование grep):

Вы уже знаете это решение, но я добавляю его с самого последнего и эффективного решения. Обратите внимание, что это менее портативное решение, но более понятное для человека.

grep -R --exclude-dir=node_modules 'some pattern' /path/to/search

РЕШЕНИЕ 3 (Ag)

Если вы часто просматриваете код, Ag (The Silver Searcher) является гораздо более быстрой альтернативой grep, настроенной для поиска кода. Например, он автоматически игнорирует файлы и каталоги, перечисленные в .gitignore, поэтому вам не нужно передавать те же громоздкие опции исключения в grep или find.

Ответ 2

Последние версии GNU Grep ( >= 2.5.2):

--exclude-dir=dir

который исключает каталоги, соответствующие шаблону dir из поиска в рекурсивном каталоге.

Итак, вы можете сделать:

grep -R --exclude-dir=node_modules 'some pattern' /path/to/search

Для получения дополнительной информации о синтаксисе и использовании см.

Для более старых GNU Greps и POSIX Grep используйте find, как предложено в других ответах.

Или просто используйте ack (Изменить: или Серебряный Searcher) и сделайте это!

Ответ 3

Если вы хотите исключить несколько каталогов:

"r" для рекурсивного "l" для печати только имен файлов, содержащих совпадения, и "i" для игнорирования различий в случае:

grep -rli --exclude-dir={dir1,dir2,dir3} keyword /path/to/search

Пример: Я хочу найти файлы, содержащие слово "привет". Я хочу выполнить поиск во всех каталогах Linux , кроме proc, загрузочной директории, sys и root:

grep -rli --exclude-dir={proc,boot,root,sys} hello /

Примечание. Пример выше должен быть root

Примечание 2 (согласно @skplunkerin): не добавляйте пробелы после запятых в {dir1,dir2,dir3}

Ответ 4

Этот синтаксис

--exclude-dir={dir1,dir2}

расширяется оболочкой (например, Bash), а не grep, в это:

--exclude-dir=dir1 --exclude-dir=dir2

Цитирование будет препятствовать расширению оболочки, поэтому это не сработает:

--exclude-dir='{dir1,dir2}'    <-- this won't work

Шаблоны, используемые с --exclude-dir - это те же шаблоны, которые описаны на странице руководства для опции --exclude:

--exclude=GLOB
    Skip files whose base name matches GLOB (using wildcard matching).
    A file-name glob can use *, ?, and [...]  as wildcards, and \ to
    quote a wildcard or backslash character literally.

Обычно оболочка пытается расширить такой шаблон, поэтому, чтобы этого избежать, вы должны процитировать его:

--exclude-dir='dir?'

Вы можете использовать фигурные скобки и процитировать шаблоны исключения следующим образом:

--exclude-dir={'dir?','dir??'}

Шаблон может охватывать несколько сегментов пути:

--exclude-dir='some*/?lse'

Это исключало бы каталог, например topdir/something/else.

Ответ 5

Часто используйте это:

grep может использоваться в сочетании с -r (рекурсивный), i (игнорировать регистр) и -o (печатает только соответствующую часть строк). Чтобы исключить files, используйте --exclude и для исключения каталогов используйте --exclude-dir.

Объединяя это, вы получите что-то вроде:

grep -rio --exclude={filenames comma separated} \
--exclude-dir={directory names comma separated} <search term> <location>

Описывая это, он звучит намного сложнее, чем есть на самом деле. Легче проиллюстрировать простым примером.

Пример:

Предположим, что я ищу текущий проект для всех мест, где я явно задал строковое значение debugger во время сеанса отладки и теперь хочу просмотреть/удалить.

Я пишу script под названием findDebugger.sh и использую grep, чтобы найти все вхождения. Однако:

Для исключений файлов - я хочу убедиться, что .eslintrc игнорируется (на самом деле это правило linting о debugger, поэтому его следует исключить). Аналогичным образом, я не хочу, чтобы мои собственные script указывались в любых результатах.

Для исключений каталогов - я хочу исключить node_modules, поскольку он содержит множество библиотек, которые ссылаются на debugger, и мне не интересны эти результаты. Также я просто хочу опустить скрытые каталоги .idea и .git, потому что я не забочусь об этих местах поиска, и хочу сохранить результаты поиска.

Итак, вот результат - я создаю script, называемый findDebugger.sh, с помощью:

#!/usr/bin/env bash
grep -rio --exclude={.eslintrc,findDebugger.sh} \
--exclude-dir={node_modules,.idea,.git} debugger .

Ответ 6

Вы можете попробовать что-то вроде grep -R search . | grep -v '^node_modules/.*'

Ответ 7

Очень полезно, особенно для тех, кто имеет дело с Node.js, где мы хотим избежать поиска внутри "node_modules":

find ./ -not -path "*/node_modules/*" -name "*.js" | xargs grep keyword

Ответ 8

Простая рабочая команда:

root/dspace# grep -r --exclude-dir={log,assetstore} "creativecommons.org"

Выше я grep для текста "creativecommons.org" в текущем каталоге "dspace" и исключить dirs {log, assetstore}.

Готово.

Ответ 9

этот работает для меня

grep <stuff> -R --exclude-dir=<your_dir>

Ответ 10

find . ! -name "node_modules" -type d 

Ответ 11

Если вы используете grepping для кода в git-репозитории, а node_modules находится в вашем .gitignore, вы можете использовать git grep. git grep ищет отслеживаемые файлы в рабочем дереве, игнорируя все из .gitignore

git grep "STUFF"

Ответ 12

Более простой способ - отфильтровать результаты с помощью grep -v.

grep -i needle -R * | grep -v node_modules