Используйте синтаксис grep --exclude/--include, чтобы не просматривать определенные файлы.
-
03-07-2019 - |
Вопрос
Я ищу веревку 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 "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
.