grep 別名可以安全地忽略多個目錄

grep 別名可以安全地忽略多個目錄

日常使用情況是:

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

(確保dir1anddir2看起來不像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)。

相關內容