ディレクトリ内の各ファイルの最初の50行を再帰的にgrepするにはどうすればよいですか?


10

ディレクトリとそのサブディレクトリにあるすべてのファイルの最初の50行を検索する必要があります。

これは再帰的な部分を行いますが、各ファイルの最初の50行だけに制限するにはどうすればよいですか?

grep -r "matching string here" .

これらのファイルの一部は巨大であり、最初の50行でのみ一致させたい。一部のファイルでメガバイトのバイナリデータを検索しないようにして、プロセスを高速化しようとしています。


一致するファイルだけを知りたいですか、それとも一致する文字列だけが欲しいですか、それともファイル名とともに一致する文字列が欲しいですか?
gniourf_gniourf 2013年

回答:


11
  • 一致するファイルだけが必要な場合:

    find . -type f -exec bash -c 'grep -q "matching string here" < <(head -n 50 "$1")' _ {} \; -printf '%p\n'
    

    または

    find . -type f -exec bash -c 'grep -q "matching string here" < <(head -n 50 "$1") && printf '%s\n' "$1"' _ {} \;
    
  • 一致する文字列のみが必要な場合:

    find . -type f -exec head -n 50 {} \; | grep "matching string here"
    

    または、より良い、

    find . -type f -exec head -q -n 50 {} + | grep "matching string here"
    
  • そして、両方が必要な場合:

    find . -type f -exec bash -c 'mapfile -t a < <(head -n 50 "$1" | grep "matching string here"); printf "$1: %s\n" "${a[@]}"' _ {} \;
    

備考。

  • sedコンボの代わりに少し簡単にすることができますhead- grep
  • 面白い記号(スペース、改行など)を含む可能性のあるファイル名に関して、3つの方法はすべて100%安全であることを強調しておきます。
  • これらの2つの方法では、最近のバージョンのbashを使用していると想定しています。
  • -exec ... +各メソッドで使用できますが、内部ループを自分でコーディングする必要があります!(軽微な演習は読者に任されています)。膨大な数のファイルがある場合、これは非常にわずかに効率的かもしれません。

4

元のようにgrep出力が必要な場合は、次のようにすることができます。

find . -type f | while read f; do 
  if head -n 50 "$f"|grep -s "matching string here"; then
    grep "matching string here" "$f" /dev/null 
  fi
done

ファイル名だけが必要な場合は、2番目のgrepをに置き換えることができますecho "$f"


1

目的の機能を実現するには、いくつかのユーティリティを組み合わせる必要があります。findコマンドを使用してディレクトリを再帰し、すべてのファイルを見つけて、head見つかった各ファイルに対してコマンドを実行します。このheadコマンドを使用して、各ファイルの最初の50行のみをダンプできます。最後に、出力をgrepにパイプして、目的の文字列を検索します。

find . -type f -exec head -n 50 {} ";" | grep "matching string here"

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.