Использовать grep --exclude/- включить синтаксис, чтобы не grep через определенные файлы
Я ищу строку foo=
в текстовых файлах в дереве каталогов. Это на общей машине Linux, у меня есть bash shell:
grep -ircl "foo=" *
В каталогах также много двоичных файлов, которые соответствуют "foo =". Поскольку эти результаты не актуальны и замедляют поиск, я хочу, чтобы grep не просматривал эти файлы (в основном изображения JPEG и PNG). Как мне это сделать?
Я знаю, что есть опции --exclude=PATTERN
и --include=PATTERN
, но каков формат шаблона? На странице man 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 и варианты не нашли ничего подходящего
Если есть лучший способ grepping только в определенных файлах, я все для этого; перемещение файлов-нарушителей не является вариантом. Я не могу искать только определенные каталоги (структура каталогов - большой беспорядок, со всем везде). Кроме того, я ничего не могу установить, поэтому мне приходится делать общие инструменты (например, grep или предлагаемая находка).
Ответы
Ответ 1
Использовать синтаксис globing оболочки:
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
, что вполне вероятно не то, что вы хотел.
Ответ 2
Если вы просто хотите пропустить двоичные файлы, я предлагаю вам посмотреть опцию -I
(верхний регистр i). Он игнорирует двоичные файлы. Я регулярно использую следующую команду:
grep -rI --exclude-dir="\.svn" "pattern" *
Он ищет рекурсивно, игнорирует двоичные файлы и не просматривает скрытые папки Subversion для любого шаблона, который я хочу. Я нахожу его псевдоним как "grepsvn" на моем ящике на работе.
Ответ 3
Пожалуйста, посмотрите ack, который предназначен именно для этих ситуаций. Ваш пример
grep -ircl --exclude=*.{png,jpg} "foo=" *
выполняется с помощью ack как
ack -icl "foo="
потому что ack никогда не выглядит в двоичных файлах по умолчанию, а -r по умолчанию. И если вы хотите только файлы CPP и H, просто выполните
ack -icl --cpp "foo="
Ответ 4
grep 2.5.3 представил параметр -exclude-dir, который будет работать так, как вы хотите.
grep -rI --exclude-dir=\.svn PATTERN .
Вы также можете установить переменную среды: GREP_OPTIONS = "- exclude-dir =.svn"
Я буду второй Энди голосовать за ack, хотя, это лучший.
Ответ 5
Я нашел это через долгое время, вы можете добавить несколько включений и исключить, например:
grep "z-index" . --include=*.js --exclude=*js/lib/* --exclude=*.min.js
Ответ 6
Предлагаемая команда:
grep -Ir --exclude="*\.svn*" "pattern" *
концептуально неверен, потому что --exclude работает в basename. Другими словами, он пропускает только .svn в текущей директории.
Ответ 7
В grep 2.5.1 вы должны добавить эту строку в профиль ~/.bashrc или ~/.bash
export GREP_OPTIONS="--exclude=\*.svn\*"
Ответ 8
Я считаю grepping grep output очень полезным:
grep -rn "foo=" . | grep -v "Binary file"
Хотя это фактически не останавливает его от поиска двоичных файлов.
Ответ 9
В CentOS 6.6/Grep 2.6.3 я должен использовать его следующим образом:
grep "term" -Hnir --include \*.php --exclude-dir "*excluded_dir*"
Обратите внимание на отсутствие равных знаков "=" (иначе --include
, --exclude
, include-dir
и --exclude-dir
игнорируются)
Ответ 10
Я дилетант, предоставленный, но вот как выглядит мой ~/.bash_profile:
export GREP_OPTIONS="-orl --exclude-dir=.svn --exclude-dir=.cache --color=auto" GREP_COLOR='1;32'
Обратите внимание, что для исключения двух каталогов мне пришлось дважды использовать -exclude-dir.
Ответ 11
Если вы не прочь использовать 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
Ответ 12
Попробуйте следующее:
$ 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
Ответ 13
Найти и xargs - ваши друзья. Используйте их для фильтрации списка файлов, а не grep --exclude
Попробуйте что-нибудь вроде
find . -not -name '*.png' -o -type f -print | xargs grep -icl "foo="
Ответ 14
эти сценарии не выполняют всю проблему... Попробуйте это лучше:
du -ha | grep -i -o "\./.*" | grep -v "\.svn\|another_file\|another_folder" | xargs grep -i -n "$1"
этот script настолько лучше, потому что он использует "реальные" регулярные выражения, чтобы избежать каталогов из поиска. просто выделите папки или имена файлов с помощью "\ |" на grep -v
наслаждайся этим!
найденный на моей оболочке Linux! XD
Ответ 15
Посмотрите @этот.
grep --exclude="*\.svn*" -rn "foo=" * | grep -v Binary | grep -v tags
Ответ 16
Опция --binary-files=without-match
для GNU grep
позволяет ей пропускать двоичные файлы. (Эквивалентно переключателю -I
, указанному в другом месте.)
(Для этого может потребоваться последняя версия grep
; 2.5.3 имеет ее, по крайней мере.)
Ответ 17
подходит для файла tcsh.alias:
alias gisrc 'grep -I -r -i --exclude="*\.svn*" --include="*\."{mm,m,h,cc,c} \!* *'
Пришло время понять, что часть {mm, m, h, cc, c} НЕ должна быть внутри кавычек.
~ Кит
Ответ 18
Если вы ищете нерекурсивно, вы можете использовать glop patterns для соответствия именам файлов.
grep "foo" *.{html,txt}
включает html и txt. Он выполняет поиск только в текущем каталоге.
Поиск в подкаталогах:
grep "foo" */*.{html,txt}
В подкаталогах:
grep "foo" */*/*.{html,txt}
Ответ 19
Чтобы игнорировать все двоичные результаты из grep
grep -Ri "pattern" * | awk '{if($1 != "Binary") print $0}'
Часть awk будет отфильтровывать все двоичные файлы foo совпадений строк
Ответ 20
Попробуйте следующее:
- Создайте папку с именем "
--F
" под currdir.. (или переместите другую папку там, где она была переименована в "--F
", т.е. double-minus-F
.
-
#> grep -i --exclude-dir="\-\-F" "pattern" *