ファイルに一致が含まれている各フォルダで Grep を実行し、コマンドを実行します。

ファイルに一致が含まれている各フォルダで Grep を実行し、コマンドを実行します。

私はgrepがファイル内の一致するものを見つけるために各フォルダからコマンドを実行するエレガントな方法を探しています。findフラグは、-execdirコンテンツではなくフォルダ/ファイル名のみを検索することを除いて、findと非常によく似ています。

現在私は次のようなものを使用しています。

grep -r "pattern" --include=\*.out -l | xargs -L 1 bash -c 'cd `dirname "$0"` && some_script.sh'

より直接的な方法はありますか?それはまるでgrep ... -execdir

答え1

find実行することができますgrep

find . -type f -name '*.out' \
    -exec grep -q -e 'pattern' {} \; \
    -execdir somescript.sh \;

見つかったパス名ごとに、パターンがファイルの行と一致することを確認するために.out使用されます。grepその場合は、見つかったファイルのディレクトリを作業ディレクトリとして使用して実行-execdirします。somescript.sh

somescript.shこれが機能するには、どこかで利用できる必要があり、スクリプトは一致するファイルを含む各ディレクトリ$PATHに対して1回ではなく、見つかった各ファイルに対して1回実行されます.out

.out一致するファイルを含む各ディレクトリでスクリプトを一度だけ実行します。

find . -type d -exec sh -c '
    for dirpath do
        if grep -q -e "pattern" "$dirpath"/*.out 2>/dev/null; then
            ( cd "$dirpath" && exec somescript.sh )
        fi
    done' sh {} +

findファイルではなくディレクトリを検索するために使用されます。バッチディレクトリが見つかると、短いインラインシェルスクリプトが実行されます。シェルスクリプトは、各ディレクトリ内のすべてのファイル(隠しディレクトリを探している間に隠しファイルを除く.out)に対してパターンを一致させようとします。一致するファイルがある場合は、作業ディレクトリが変更されるサブシェルを起動してスクリプトを実行します。findsomescript.sh

答え2

一致するファイルが 1 つ以上含まれる各ディレクトリに対してout一度だけスクリプトを実行し、grep各ファイルに対して 1 つずつ実行したくない場合は、次のようにします。

P="pattern" find . -name '*.out' -type f -exec gawk '
  BEGINFILE {
    dir = FILENAME; sub("/[^/]*$", "", dir)
    if (dir in found) nextfile
  }
  $0 ~ ENVIRON["P"] {
    printf "%s\0", dir
    found[dir]
    nextfile
  }' {} + | xargs -r0 sh -c '
    for dir do
      (cd "$dir" && exec somescript.sh)
    done' sh

これはできるだけ少ないプロセスを実行し、gawkできるだけ少ないファイルを読み取ります(各ファイルの内容はできるだけ少なくなります)。

GNUxargsまたは互換ファイル名には、現在のロケールで有効な文字を形成しない一連のバイトが含まれていないとします。

GNUgrep呼び出し(およびGNU 、、、dirname)の使用:sortxargs

grep -rlZ --include='*.out' pattern . |
  xargs -r0 dirname -z |
  sort -zu |
  xargs -r0 sh -c '
    for dir do
      (cd "$dir" && exec somescript.sh)
    done' sh

out以前の解決策とは異なり、この方法では、一致するファイルが見つかったディレクトリ内のファイルを含むすべてのファイルを検索します。 GNU はgrepgrep よりも効率的であるため、どれだけの過剰なgawkデータが greping されるかに応じて、依然として効率的である可能性があります。

関連情報