Я хочу пройти все подкаталоги, за исключением каталога node_modules.
Как я могу исключить каталоги из grep -R?
Ответ 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 для Выбор файлов и каталогов
- Связанный ответ StackOverflow Используйте синтаксис grep --exclude/- include, чтобы не grep через определенные файлы
Для более старых 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