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

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

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 или предлагаемый поиск ).

21.10.2008 13:41:01
Только для справки, использованные аргументы: -c подсчитывать совпадения в файле -i без
Piskvor left the building 21.10.2008 13:56:24
Более быстрый способ исключить svn dirs - это то --exclude-dir=.svn, что grep вообще их не использует
orip 2.12.2009 10:14:26
Пару педантичных точек, которые люди могут знать: 1. Обратите внимание на отсутствие кавычек вокруг глобуса: --exclude = ' . {Png, jpg}' не работает (по крайней мере, с моей версией GNU grep), потому что grep не поддерживает {} в его глобусах. Вышесказанное расширено до «--exclude = .png --exclude = *. Jpg» (при условии, что в cwd нет совпадений с файлами - очень маловероятно, поскольку вы обычно не начинаете имена файлов с «--exclude =»), что grep любит просто отлично. 2. --exclude является расширением GNU и не является частью определения grep в POSIX, поэтому, если вы пишете сценарии, использующие это, имейте в виду, что они не обязательно будут работать в не-GNU системах.
ijw 20.01.2011 14:11:29
Полный пример использования exclude-dir:grep -r --exclude-dir=var "pattern" .
Tisch 13.08.2015 10:01:09
22 ОТВЕТА
РЕШЕНИЕ

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

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, что, скорее всего, не то, что вы хотели.

759
14.12.2011 22:53:57
Я не знаю почему, но мне пришлось процитировать шаблон включения следующим образом:grep pattern -r --include="*.{cpp,h}" rootdir
topek 9.12.2011 07:41:31
@topek: Хорошая мысль - если у вас есть какие-либо файлы .cpp / .h в вашем текущем каталоге, то оболочка раскроет глобус перед вызовом grep, так что в итоге вы получите командную строку, например grep pattern -r --include=foo.cpp --include=bar.h rootdir, которая будет искать только файлы по имени foo.cppили bar.h. Если у вас нет файлов, соответствующих глобу в текущем каталоге, оболочка передает глоб в grep, который правильно его интерпретирует.
Adam Rosenfield 14.12.2011 22:51:57
Я только что понял, что глобус используется только для соответствия имени файла. Чтобы исключить весь каталог, нужна --exclude-dirопция. Однако применяются те же правила. Совпадает только имя файла каталога, а не путь.
Krzysztof Jabłoński 22.09.2015 17:00:50
--includeкажется, не работает после --exclude. Я полагаю, что не имеет смысла даже пытаться, за исключением того, что у меня есть aliasgrep с длинным списком --excludeи --exclude-dir, который я использую для поиска кода, игнорирования библиотек и файлов подкачки и прочего. Я бы надеялся , что grep -r --exclude='*.foo' --include='*.bar'будет работать, так что я мог бы ограничить мой , aliasчтобы --include='*.bar'только, но это , кажется, игнорируют --includeи включают в себя все , что это не .foo файл. Менять порядок --includeи --excludeработает, но увы, это не поможет с моим alias.
Michael Scheper 10.08.2016 13:49:05
как мы можем читать чьи-то мысли, чтобы получить правила для этого PATTERN. Полчаса я не могу найти описания того, что они там ждут
Arkady 9.08.2018 08:22:59

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

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

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

9
21.10.2008 13:44:45
Вы можете использовать, grep -Iчтобы пропустить двоичные файлы.
Nathan Fellman 27.08.2009 06:17:27
Я также сделал это, когда я был молодым ... теперь я знаю лучше, и когда сталкиваюсь с проблемой, первым делом это
gcb 18.05.2012 18:28:28
grep grep удалит цветные блики.
Max Li 27.03.2020 22:09:19

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

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

find . -not -name '*.png' -o -type f -print | xargs grep -icl "foo="
2
21.10.2008 13:45:26
Это не работает с именами файлов с пробелами, но эту проблему легко решить, используя print0 вместо print и добавив опцию -0 в xargs.
Adam Rosenfield 21.10.2008 13:46:33

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

$ найти. -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
21.10.2008 13:54:13
Это не работает с именами файлов с пробелами, но эту проблему легко решить, используя print0 вместо print и добавив опцию -0 в xargs.
Adam Rosenfield 21.10.2008 13:58:27

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

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

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

219
28.06.2017 12:58:53
Спасибо, это очень полезно для некоторых других сценариев, с которыми я столкнулся.
Piskvor left the building 21.10.2008 14:28:23
--exclude-dirне доступен везде у моего RH box при работе с GNU grep 2.5.1 его нет.
gcb 18.05.2012 18:23:03
Любые предложения о том, что использовать, когда --exclude-dirнедоступно? Во всех моих попытках, похоже, --excludeне отвечает всем требованиям .
JMTyler 31.03.2014 18:05:53
Вы всегда можете загрузить последний источник grep из GNU и выполнить команду 'configure; делать; sudo make install '. Это одна из первых вещей, которую я делаю на Mac или более старом дистрибутиве Linunx.
Jonathan Hartley 25.04.2014 09:50:31
Именно то, что мне было нужно. На самом деле, я использую Git. Так, --exclude-dir="\.git". :-)
Ionică Bizău 2.07.2014 19:13:24

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

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

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

ack -icl "foo="

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

ack -icl --cpp "foo="
64
21.10.2008 14:18:19
Выглядит хорошо, попробую автономную версию Perl в следующий раз, спасибо.
Piskvor left the building 21.10.2008 14:39:40
Хороший звонок, я больше не могу жить без ack.
Chance 15.11.2010 21:21:42
stackoverflow.com/questions/667471/… - Это позволит вам получить доступ к windows, если вы работаете с grep.
TamusJRoyce 15.12.2010 16:58:45
@Chance Может быть, вы хотите silversearcher-ag , просто apt-getв Ubuntu :)
Justme0 18.04.2016 08:09:46
не путать сawk
jasonleonhard 24.03.2020 20:07:13

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

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

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

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

2
5.11.2008 08:30:45

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

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

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

12
17.12.2008 18:56:38
Да, это не работает для меня. Тот, который работал для меня, был: exclude-dir = .svn
Taryn East 31.01.2011 18:07:10
@ Николя спасибо! Я рвал на себе волосы о том, почему это не сработает. Скажите, есть ли способ узнать это на странице руководства? Все, что он говорит, это соответствует "УЗОРУ". Редактировать man-страницу говорит "файл", как объяснено здесь fixunix.com/unix/…
13ren 29.06.2011 16:40:36

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

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

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

Я второй голос Энди за кв, хотя, это лучший.

35
23.05.2017 11:47:25
+1 за упоминание точного номера версии; У меня есть grep 2.5.1 и опция exclude-dir недоступна
James 25.07.2011 21:25:11

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

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

1
7.04.2009 11:04:44

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

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

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

5
27.08.2009 06:02:29

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

export GREP_OPTIONS="--exclude=\*.svn\*"
11
1.04.2010 10:13:14

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

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

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

0
24.04.2012 06:39:23

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

grep --exclude="*\.svn*" -rn "foo=" * | grep -v Binary | grep -v tags
2
20.11.2011 00:57:46
Вещи, которые достигают приблизительно этого, были описаны в других сообщениях; более того, это неправильно, так как при различных настройках макета он будет портить номера строк и тому подобное или исключать строки контекста, которые были желательны.
Chris Morgan 10.11.2010 05:38:37
как вы можете использовать несколько опций "-v" одновременно?
Open the way 13.12.2012 12:19:09

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

  1. Создайте папку с именем « --F» под currdir .. (или связать другую папку там переименованную « --F» то есть double-minus-F.
  2. #> grep -i --exclude-dir="\-\-F" "pattern" *
-2
7.12.2012 16:11:32

Если вы не против использования 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конструкций, сколько у вас есть шаблонов.

На 4-й строке вам нужен другой -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

7
15.11.2011 18:28:16
Одна поправка, которую я бы предложил: включить -falseсразу после каждого, -pruneтак что если вы забыли использовать, -print0или какая-то execкоманда фактически не напечатает файлы, которые вы хотели исключить: -name "*.png" -prune -false -o name "*.gif -prune -false...
OnlineCop 20.11.2019 15:40:39

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

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

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

1
2.04.2012 17:52:48

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

grep "z-index" . --include=*.js --exclude=*js/lib/* --exclude=*.min.js
25
20.12.2012 04:54:44
Лучше объединить их в список, например: --exclude = {pattern1, pattern2, pattern3}
Yasser Sinjab 15.05.2017 12:33:00

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

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

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

7
7.11.2014 18:43:19

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

grep "foo" *.{html,txt}

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

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

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

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

   grep "foo" */*/*.{html,txt}
3
22.08.2016 03:15:30

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

ripgrep

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

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

rg "some_pattern"

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

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

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

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

3
14.05.2018 23:02:37

git grep

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

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

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

git grep --no-index "some_pattern"

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

6
14.05.2018 23:01:51