Повседневное использование:
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
передавать опции в grep
like с помощью специального массива, если ваша оболочка их поддерживает:
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
).