ディレクトリを Grep し、行番号を含むリストを返します。

ディレクトリを Grep し、行番号を含むリストを返します。

私は現在、bashスクリプトとこれらすべての面白いものについてもっと学びようとしています。

find $path | xargs grep -n $pattern | awk '{print $1}'

これが動作している間に車輪を再発明しているのだろうか。ディレクトリを検索し、ファイル内のパターンを見つけ、行番号を含むリストを返すより良い方法はありますか?

答え1

多くのgrepバリアントが再帰オプションを実装します。たとえば、GNU grep

-R, -r, --recursive
          Read all files under each directory, recursively; this is equivalent to the -d recurse option.

その後、以下を削除できますfind

grep -n -r $pattern $path | awk '{ print $1 }'

ただし、これは単純な行番号以上のものを保存します。awk最初の列を印刷します。この例

src/main/package/A.java:3:import java.util.Map;
src/main/package/A.java:5:import javax.security.auth.Subject;
src/main/package/A.java:6:import javax.security.auth.callback.CallbackHandler;

次のように印刷されます。

src/main/package/A.java:3:import
src/main/package/A.java:5:import
src/main/package/A.java:6:import

:import各行に注意してください。これを使用してsed出力をフィルタリングできます。

:ファイル名にaが表示される可能性があるため、-Zgrepオプションを使用してファイル名の後にnul文字(\ 0)を出力できます。

grep -rZn $pattern $path | sed -e "s/[[:cntrl:]]\([0-9][0-9]*\).*/:\1/" 

前と同じ例では

src/main/package/A.java:3
src/main/package/A.java:5
src/main/package/A.java:6

答え2

最初の部分では、xargsファイル名に空白文字がない場合にのみ機能することに注意してください。\'"バラよりLinuxディレクトリの内容全体から単語を検索する方法説明と代替案を見つけてください。

また、変数の置換は常に二重引用符で囲んでください"$path"。二重引用符がない場合、シェルは値のスペースとワイルドカードを拡張するため、ファイル名にスペースまたは$pathワイルドカードが含まれている場合は引用符なしで使用すると中断されます。同じです$pattern。 (笑いのために引用符を省略し、h*という名前のファイルを含むディレクトリで検索してみてください。)hihello

あなたのバージョンにディレクトリを再帰的に移動するオプションがgrepある場合、これは必要ありません。このオプションは、Linux、FreeBSD、Mac OS X、Cygwinなどで利用できます。それ以外の場合:-rfind-r

find "$path" -type f -exec grep -Hn "$pattern" {} + | awk -F: '{print $1 ":" $2}'

awkまた、ファイル名と行番号のみを印刷するように上記の呼び出しを修正しました。また、ファイルが1つしかない場合でも、常にファイル名を印刷する-Hオプションをに渡しました。grepこのコードは、ファイル名に改行文字が含まれていないと想定しています:。可能であれば、状況は複雑になり、どちらかを選択することをお勧めします。GNU grepに依存する-Zオプションまたはファイルを個別に処理します。

find "$path" -type f -exec sh -c 'for x; do grep -n "$0" <"$x" | awk -v fn="$x" -F: 'print fn ":" $1'; done' "$pattern" {} +

答え3

私はそれを削除し、grep次を使用しますawk

find $path -type f -print0 | xargs -0 awk "/$pattern/{print FILENAME,FNR}"

grepしかし、使用cut

find $path -type f -print0 | xargs -0 grep -nH "$pattern" | cut -d: -f1,2

-type f一般的ではないファイル形式(シンボリックリンク、ディレクトリ、ソケット)を検索しようとしたとき(grepまたはawkで)エラーが発生しないように、このセクションを含めてください。パイプやソケットで読む必要があるときに別のプログラムを使用している場合は、そのプログラムを台無しにすることができます。

find ... -print0 | xargs -0ファイル名にスペースが含まれる問題を修正しました。すべてのUNIXシステムでは使用できませんが、ほとんどのシステムで使用できます。

答え4

また、確認-cし、-n便利なオプションを確認してください。

関連情報