すべてのサブディレクトリ内の文字列に対するこの grep が機能しないのはなぜですか?

すべてのサブディレクトリ内の文字列に対するこの grep が機能しないのはなぜですか?

これは私が実行しようとしているコマンドです。

grep -r "printf" *.c

cwd にあるすべてのファイルからすべての printf 行を取得しようとしています.c。現在、現在のディレクトリは Desktop で、.cDesktop の下のサブディレクトリには少なくとも 10 ~ 15 個のファイルがありますが、このコマンドでは一致するものがまったく表示されません。この場合、これを機能させるにはどうすればよいですか?

答え1

もし、するなら:

grep -r "printf" *.c

シェルは、現在のディレクトリ内で*.cで終わるすべてのファイル/ディレクトリに展開します.c。そのようなファイル/ディレクトリが存在しない場合は、パターンは文字通りに扱われます (おそらくnullglob設定されていない)。

ご覧のとおり、現在のディレクトリ.cにはファイルがないため、またはファイルがあってもprintfその中にファイルがないため、現在のパターンは現在のディレクトリの下には移動せず、空の出力になります。

--include選択したファイルのみを検索し、再帰的に走査するには、を使用する必要があります-r

grep -r --include="*.c" "printf" .

上記は、現在のディレクトリから再帰的にすべての.cファイルで文字列 (パターン)を検索します。printf

すべてのシンボリックリンクをたどりたい場合:

grep -R --include="*.c" "printf" .

答え2

コマンドが機能しない理由を知りたい場合は、もう一つの答えそれを機能させる方法を知りたい場合は、別のアプローチがありますディレクトリ内の特定の拡張子を持つファイルをGrepで検索する の機能でbash はなく の 機能を使用する(そのため、だけでなく 、やなどgrep の任意のコマンドで機能します):wccptargrep

オンにするシュエルオプションイオンglobstarをコマンドで

shopt -s globstar

これにより**、ファイル名の構成要素はここと下のすべてを意味します。つまり、 にいる場合Desktop、 はディレクトリ **内のすべてを意味します。Desktopおよびそのサブディレクトリ.その後、

grep "printf" **/*.c

.cと の下にあるすべてのファイルを検索しますDesktop。 を指定する必要はありません。シェルが自動的に再帰を実行します。また、パス名拡張パターン (別名 glob またはワイルドカード) に が含まれているため、-rを指定する必要もありません。--include*.c


あなたはできるあなたnset オプションを使用しますshopt -u

関連情報