日常使用情況是:
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
)。