日常使用情况是:
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}'
足够好(尽管添加新东西时需要维护)。如果目录被 grep 排除,如何至少在 stderr 中添加一个简短的警告?
答案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
anddir2
看起来不像find
谓词)。
-exec sh...+
如果您不关心这些警告消息,请删除。
当你如此显着地改变它的行为时,使用它grep
作为你的别名是一个坏主意。
如果您需要将选项传递给grep
,您可以使用GREP_OPTIONS
如下变量:
GREP_OPTIONS=-i mygrep foo dir
但请注意,对该选项的支持将在 的未来版本中删除grep
,因此更好的选择可能是提供一种方法,mygrep
将选项传递grep
给专用数组(如果您的 shell 支持它们):
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
(并确保您不--
作为选项参数传递,就像您想排除文件一样--
,请使用--exclude=--
,而不是--exclude --
例如。这也排除了像mygrep -e pattern1 -e pattern2 -- dir
或 之类的用法mygrep -f patternfile -- dir
)。