複数のディレクトリを安全に無視するための grep エイリアス

複数のディレクトリを安全に無視するための grep エイリアス

日常的な使用方法は次のとおりです。

grep -rIn pattern directory

避けたいファイルがいくつかあります。それらは、ある時点で次のようなパスを持つディレクトリにあります: app/lib/bower/lodash、、app/lib/bower/paho-mqtt-jsapp/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そして-HGNU拡張機能です)。

使用:

mygrep pattern dir1 dir2

(述語のように見えないようdir1に注意してください)。dir2find

-exec sh...+これらの警告メッセージを気にしない場合は削除してください。

grep動作を大幅に変更する場合、エイリアス名として使用するのはお勧めできません。

にオプションを渡す必要がある場合はgrep、次のような変数を使用できますGREP_OPTIONS

GREP_OPTIONS=-i mygrep foo dir

ただし、そのオプションのサポートは の将来のバージョンでは削除される予定であることに注意してください。そのため、シェルがサポートしている場合は、専用の配列を使用して などにオプションを渡すgrep方法を提供する方がよい場合があります。mygrepgrep

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)。

関連情報