grep alias для безопасного игнорирования нескольких каталогов

grep alias для безопасного игнорирования нескольких каталогов

Повседневное использование:

grep -rIn pattern directory

Есть некоторые файлы, которых я хочу избежать, они находятся в каталогах, в которых в какой-то момент есть следующий путь: app/lib/bower/lodash, app/lib/bower/paho-mqtt-js, app/lib/bower/socket-io-client.

Идеальное решение — обнаружить app/lib/bower/на пути, но это сложно. Возможно ли это?

Я придумал:

alias grep='grep --exclude-dir={lodash,paho-mqtt-js,socket-io-client}'

Достаточно хорошо (хотя требует обслуживания при добавлении нового материала). Как хотя бы добавить короткое предупреждение в stderr, если каталог исключен grep?

решение1

Я бы использовал find:

mygrep() (
  pattern=$1; shift
  find "$@" -type d -path '*/app/lib/bower' -exec sh -c '
    printf >&2 "Warning: ignoring \"%s\" directory\n" "$@"
    ' sh {} + -prune -o -type f -exec grep -IHne "$pattern" {} +
)

( -Iи -Hявляющиеся расширениями GNU).

Использовать как:

mygrep pattern dir1 dir2

(убедитесь, что dir1и dir2не выглядят как findпредикаты).

Удалите -exec sh...+эти предупреждающие сообщения, если они вас не интересуют.

grepИспользовать в качестве псевдонима имя — плохая идея, если вы так кардинально меняете его поведение.

Если вам необходимо передать параметры grep, вы можете использовать GREP_OPTIONSпеременную следующим образом:

GREP_OPTIONS=-i mygrep foo dir

Но учтите, что поддержка этой опции будет удалена в будущих версиях grep, поэтому лучшим вариантом может быть предоставление возможности mygrepпередавать опции в greplike с помощью специального массива, если ваша оболочка их поддерживает:

mygrep() (
  pattern=$1; shift
  find "$@" -type d -path '*/app/lib/bower' -exec sh -c '
    printf >&2 "Warning: ignoring \"%s\" directory\n" "$@"
    ' sh {} + -prune -o -type f -exec \
    grep -IHne "${g[@]}" "$pattern" {} +
)

g=(-i --exclude-dir=.git); mygrep foo dir1 dir2

Или используйте --, чтобы указать, mygrepгде заканчиваются варианты:

mygrep() (
  grep_options=()
  for i do
    grep_options+=("$i")
    shift
    [ "$i" != "--" ] || break
  done
  pattern=${1?need a pattern}; shift
  find "$@" -type d -path '*/app/lib/bower' -exec sh -c '
    printf >&2 "Warning: ignoring \"%s\" directory\n" "$@"
    ' sh {} + -prune -o -type f -exec \
    grep -H "${grep_options[@]}" "$pattern" {} +
)

mygrep -nI --exclude-dir=.git -- pattern dir1 dir2

(и убедитесь, что вы не передаете --в качестве аргументов option, например, если вы хотите исключить файлы --, используйте --exclude=--, а --exclude --не . Это также исключает использование типа mygrep -e pattern1 -e pattern2 -- dirили mygrep -f patternfile -- dir).

Связанный контент