it-swarm.com.ru

Используйте синтаксис grep --exclude / - include, чтобы не просматривать определенные файлы

Я ищу строку foo= в текстовых файлах в дереве каталогов. Это на обычной машине Linux, у меня есть Bash Shell:

grep -ircl "foo=" *

В каталогах также много бинарных файлов, которые соответствуют "foo =". Поскольку эти результаты не релевантны и замедляют поиск, я хочу, чтобы grep пропустил поиск этих файлов (в основном изображений JPEG и PNG). Как бы я это сделал?

Я знаю, что есть опции --exclude=PATTERN и --include=PATTERN, но каков формат шаблона? Страница руководства grep гласит:

--include=PATTERN     Recurse in directories only searching file matching PATTERN.
--exclude=PATTERN     Recurse in directories skip file matching PATTERN.

Поиск по grep include, grep include exclude, grep exclude и варианты не нашли ничего подходящего

Если есть лучший способ поиска только в определенных файлах, я за все; перемещение оскорбительных файлов не вариант. Я не могу искать только определенные каталоги (структура каталогов - большой беспорядок, со всем везде). Кроме того, я ничего не могу установить, поэтому мне приходится иметь дело с общими инструментами (такими как grep или предлагаемыми find).

721
Piskvor

Используйте синтаксис командной оболочки:

grep pattern -r --include=\*.{cpp,h} rootdir

Синтаксис --exclude идентичен.

Обратите внимание, что звезду экранируют с помощью обратной косой черты, чтобы предотвратить ее раскрытие оболочкой (цитирование, такое как --include="*.{cpp,h}", также будет работать). В противном случае, если в текущем рабочем каталоге есть файлы, соответствующие шаблону, командная строка расширится до чего-то вроде grep pattern -r --include=foo.cpp --include=bar.h rootdir, который будет искать только файлы с именами foo.cpp и bar.h, что, скорее всего, не то, что вам нужно.

694
Adam Rosenfield

Если вы просто хотите пропустить двоичные файлы, я предлагаю вам взглянуть на параметр -I (верхний регистр i). Он игнорирует двоичные файлы. Я регулярно использую следующую команду:

grep -rI --exclude-dir="\.svn" "pattern" *

Он ищет рекурсивно, игнорирует двоичные файлы и не ищет в скрытых папках Subversion какой-либо шаблон, который мне нужен. У меня есть псевдоним "grepsvn" на моей коробке на работе.

211
rmeador

Пожалуйста, посмотрите на ack , который предназначен именно для этих ситуаций. Ваш пример

grep -ircl --exclude=*.{png,jpg} "foo=" *

делается с Ack как

ack -icl "foo="

потому что ack никогда не просматривает двоичные файлы по умолчанию, а -r включен по умолчанию. И если вы хотите только файлы CPP и H, то просто сделайте

ack -icl --cpp "foo="
62
Andy Lester

grep 2.5.3 ввел параметр --exclude-dir, который будет работать так, как вы хотите.

grep -rI --exclude-dir=\.svn PATTERN .

Вы также можете установить переменную окружения: GREP_OPTIONS = "- exclude-dir = .svn"

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

34
Corey

Я обнаружил, что после долгого времени вы можете добавить несколько включений и исключений, таких как:

grep "z-index" . --include=*.js --exclude=*js/lib/* --exclude=*.min.js
24
Rushabh Mehta

Предлагаемая команда:

grep -Ir --exclude="*\.svn*" "pattern" *

концептуально неверно, потому что --exclude работает с базовым именем. Другими словами, он пропустит только .svn в текущем каталоге.

12
Nicola

В grep 2.5.1 вы должны добавить эту строку в профиль ~/.bashrc или ~/.bash

export GREP_OPTIONS="--exclude=\*.svn\*"
11
deric

Я считаю, что вывод grep иногда очень полезен:

grep -rn "foo=" . | grep -v "Binary file"

Тем не менее, это на самом деле не мешает искать двоичные файлы.

9
Aaron Maenpaa

На CentOS 6.6/Grep 2.6.3 я должен использовать это так:

grep "term" -Hnir --include \*.php --exclude-dir "*excluded_dir*"

Обратите внимание на отсутствие знаков равенства "=" (в противном случае --include, --exclude, include-dir и --exclude-dir игнорируются)

7
aesede

Если вы не против использования find, мне нравится его функция -Prune:


find [directory] \
        -name "pattern_to_exclude" -Prune \
     -o -name "another_pattern_to_exclude" -Prune \
     -o -name "pattern_to_INCLUDE" -print0 \
| xargs -0 -I FILENAME grep -IR "pattern" FILENAME

В первой строке вы указываете каталог, который хотите найти. Например, . (текущий каталог) является допустимым путем.

Во 2-й и 3-й строках используйте "*.png", "*.gif", "*.jpg" и т.д. Используйте столько конструкций -o -name "..." -Prune, сколько у вас есть шаблонов.

В четвертой строке вам нужен еще один -o (он задает "или" для find), шаблоны, которые вы действительно хотите, и вам нужен либо -print, либо -print0 в конце. Если вы просто хотите, чтобы "все остальное" оставалось после удаления изображений *.gif, *.png и т.д., То используйте -o -print0, и с 4-й строкой все готово.

Наконец, на 5-й строке находится канал к xargs, который берет каждый из этих результирующих файлов и сохраняет их в переменной FILENAME. Затем он передает grep флаги -IR, "pattern", а затем FILENAME расширяется xargs, чтобы стать тем списком имен файлов, найденных find.

Для вашего конкретного вопроса утверждение может выглядеть примерно так:


find . \
     -name "*.png" -Prune \
     -o -name "*.gif" -Prune \
     -o -name "*.svn" -Prune \
     -o -print0 | xargs -0 -I FILES grep -IR "foo=" FILES
6
OnlineCop

Конечно, я дилетант, но вот как выглядит мой ~/.bash_profile:

 export GREP_OPTIONS = "- orl --exclude-dir = .svn --exclude-dir = .cache --color = auto" GREP_COLOR = '1; 32' 

Обратите внимание, что для исключения двух каталогов мне пришлось дважды использовать --exclude-dir.

5
4D4M

git grep

Используйте git grep, который оптимизирован для производительности и предназначен для поиска по определенным файлам.

По умолчанию он игнорирует двоичные файлы и учитывает ваш .gitignore. Если вы не работаете со структурой Git, вы все равно можете использовать ее, передав --no-index.

Пример синтаксиса:

git grep --no-index "some_pattern"

Дополнительные примеры см .:

4
kenorb

Попробуй это:

 $ найти. -name "* .txt" -type f -print | файл xargs | grep "foo =" | cut -d: -f1 

Основан здесь: http://www.unix.com/Shell-programming-scripting/42573-search-files-exclusion-binary-files.html

3
Gravstar

Если вы ищете не рекурсивно, вы можете использовать шаблоны glop для соответствия именам файлов.

grep "foo" *.{html,txt}

включает в себя HTML и TXT. Он ищет только в текущем каталоге.

Для поиска в подкаталогах:

   grep "foo" */*.{html,txt}

В подкаталогах:

   grep "foo" */*/*.{html,txt}
3
Stéphane Laurent

Смотри @ этот.

grep --exclude="*\.svn*" -rn "foo=" * | grep -v Binary | grep -v tags
2
suhas tawade

эти сценарии не решают всех проблем ... Попробуйте это лучше:

du -ha | grep -i -o "\./.*" | grep -v "\.svn\|another_file\|another_folder" | xargs grep -i -n "$1"

этот скрипт настолько лучше, потому что он использует "настоящие" регулярные выражения, чтобы избежать поиска каталогов. просто отдельные имена папок или файлов с помощью "\ |" на grep -v

наслаждайся этим! нашел на моем linux Shell! XD

2
villalvilla

В каталогах также много бинарных файлов. Я не могу искать только определенные каталоги (структура каталогов - большой беспорядок). Есть ли лучший способ поиска только в определенных файлах?

ripgrep

Это один из самых быстрых инструментов, предназначенных для рекурсивного поиска в вашем текущем каталоге. Это написано в Rust , построено поверх Rge's regex engine для максимальной эффективности. Проверьте подробный анализ здесь .

Так что вы можете просто запустить:

rg "some_pattern"

Он уважает ваш .gitignore и автоматически пропускает скрытые файлы/каталоги и двоичные файлы.

Вы по-прежнему можете настраивать включение или исключение файлов и каталогов, используя -g/--glob. Правила Globbing соответствуют .gitignore globs. Проверьте man rg для помощи.

Дополнительные примеры см .: Как исключить некоторые файлы, не соответствующие определенным расширениям, с помощью grep?

В macOS вы можете установить через brew install ripgrep.

2
kenorb

найди и xargs твои друзья. Используйте их для фильтрации списка файлов, а не grep --exclude

Попробуйте что-то вроде

find . -not -name '*.png' -o -type f -print | xargs grep -icl "foo="
2
Andrew Stein

подходит для tcsh .alias файла:

alias gisrc 'grep -I -r -i --exclude="*\.svn*" --include="*\."{mm,m,h,cc,c} \!* *'

Мне потребовалось время, чтобы понять, что часть {mm, m, h, cc, c} НЕ должна быть внутри кавычек. ~ Keith

1
Keith Knauber

Параметр --binary-files=without-match для GNU grep позволяет пропустить двоичные файлы. (Эквивалентно переключателю -I, упомянутому в другом месте.)

(Для этого может потребоваться последняя версия grep; как минимум, у 2.5.3.)

1
mjs

Чтобы игнорировать все двоичные результаты от grep

grep -Ri "pattern" * | awk '{if($1 != "Binary") print $0}'

Часть awk отфильтрует все строки двоичного файла foo match

0
lathomas64