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

StackOverflow https://stackoverflow.com/questions/221921

Вопрос

Я ищу веревку 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 включить, grep включить исключить, grep исключить и варианты не нашел ничего актуального

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

Это было полезно?

Решение

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

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

Другие советы

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

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

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

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

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

сделано с ack как

ack -icl "foo="

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

ack -icl --cpp "foo="

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

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

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

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

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

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

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

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

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

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

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

Я нахожу вывод grep grep очень полезным:

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

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

В CentOS 6.6 / Grep 2.6.3 я должен использовать его следующим образом:

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

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

Если вы не против использования 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 ), шаблоны, которые вы действительно хотите, и вам нужен либо < code> -print или -print0 в конце. Если вы просто хотите " все остальное " который остается после обрезки изображений *. gif , *. png и т. д., а затем используйте -o -print0 и вы закончили с 4-й строкой.

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

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

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

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

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

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

git grep

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

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

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

git grep --no-index "some_pattern"

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

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

 $ find . -name "*.txt" -type f -print | xargs file | grep "foo=" | cut -d: -f1

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

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

grep "foo" *.{html,txt}

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

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

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

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

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

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

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

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

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

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

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

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

Посмотри @ вот это.

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

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

ripgrep

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

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

rg "some_pattern"

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

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

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

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

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

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

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

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

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

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

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

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

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

<Ол>
  • Создайте папку с именем " - F " под currdir .. (или связать другую папку, переименованную в « - F », то есть double-minus-F .
  • <Литий> <код> # & GT; grep -i --exclude-dir = " \ - \ - F " & Quot; шаблон & Quot; *
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top