「grep」コマンドを使用してサブディレクトリを含むテキストを検索する方法


373

特定のテキスト文字列を含むすべてのファイルを検索したい。grepコマンドは動作しますが、私は(私は私の現在のディレクトリのためにそれを行うことができますのみ)すべてのディレクトリのためにそれを使用する方法がわかりません。読んman grepでみましたが、助けにはなりませんでした。


grep -RIn <yor pattern> *現在のディレクトリからすべてのテキストファイルを検索します。だけでなく、grepをして* .Cなどのファイルパターンに再帰的に私の検索を行う方法がわから

1
--include="*.C"@Lekensteynのおかげで、オプション付きのワイルドカード@ user311346。
ボブ・スタイン

findおよびgrepの組み合わせを使用して、現在およびすべてのサブディレクトリ内の文字列をファイルで再帰的に検索します。このチェックwilddiary.com/find-files-containing-my-text
Drona

回答:


487

使用する方が良いでしょう

grep -rl "string" /path

どこ

  • -r(または--recursive)オプションは、のすべてのサブディレクトリも横断するために使用されますが/path
  • -l(または--files-with-matches)オプションは、一致するファイルのファイル名のみを印刷し、一致する行は印刷しないために使用されます(これはgrep、このオプションとの最初の一致でファイルの読み取りを停止すると、速度も向上する可能性があります)。

13
実際、「文字列」が検索するテキストパターンである場合、その機能を使用することをお勧めします。そうしないと、文字列に含まれるドットだけでなく、正規表現で意味を持つドットまたは特殊文字が文字列に含まれる場合に問題に直面する可能性があります、 そのまま。次に、「固定文字列」用の-rlFスイッチを使用します-F(たとえば、正規表現ではありません)。もちろん、タスクが正規表現を使用していた場合は、すみません。確かに、-rなしの同じ理論でも、人々はgrep検索を「テキスト」と見なし、正規表現として何かを意味する特別な問題を引き起こすことがよくあります。
LGB

4
-i大文字と小文字を区別しないフラグもあります。
マルコセッピ

3
私は--recursiveオプションを表示したいだけで、多くのオプションと使用シナリオがあります。私は@dmityugovから受け入れられた回答から始め、なしで動作するように修正しましたfind
-enzotib

1
@NN:完了:-)
enzotib

3
@ScottBiggs:オプション付き--include '*.h'
enzotib

167

ファイル内で一致する行を探している場合、私のお気に入りのコマンドは次のとおりです。

grep -Hrn 'search term' path/to/files
  • -H ファイル名を印刷します(複数のファイルが検索される場合に暗示されます)
  • -r 再帰的検索を行います
  • -n 行番号を印刷します

path/to/files.現在のディレクトリで検索することができます

私が非常に便利だと思うその他のオプション:

  • -Iバイナリファイルを無視します(補足:-aすべてのファイルをテキストとして扱います)
  • -Fsearch term正規表現ではなくリテラルとして扱う
  • -i 大文字と小文字を区別しない検索を行う
  • --color=always配管するときでも色を強制するlesslessサポートカラーを作成するには、-rオプションを使用する必要があります。

    grep -Hrn search . | less -r
    
  • --exclude-dir=dir.svnやなどのディレクトリを除外するのに便利です.git

出力例


13
-Hフォルダー上のファイルは、おそらく複数のファイルがある場合、冗長です。実際、manページには、-H, --with-filename: Print the file name for each match. This is the default when there is more than one file to search.
enzotib

私はそれを知りませんでした、それはいつも私が期待したように働きました。ファイルを探すときのデフォルトのコマンドです。
レーケンシュタイン

1
たとえば、拡張子が.aのファイルのみを検討する(およびこれを-rと組み合わせる)方法はありますか?
-user2413

6
@ user2413試してください--include '*.*'
Lekensteyn

1
@alper trygrep --exclude='*~' ...
Lekensteyn

24

次のようなものを使用できると思います。

find /path -type f -exec grep -l "string" {} \;

コメントからの説明

findは、指定されたパスのサブディレクトリ内のファイルやディレクトリやリンクなどの他のオブジェクトを検索できるコマンドです。filesnamesが満たすべきマスクを指定しない場合、すべてのディレクトリオブジェクトが列挙されます。

  • -type f ディレクトリなどではなく、ファイルのみを処理することを指定します。
  • -exec grep見つかったすべてのファイルについて、grepコマンドを実行し、そのファイル名を引数として{}ファイル名に置き換えて実行することを指定します

3
知らない人のために、追加する-name '*.py'と「.py」で終わるファイルに一致が制限されます。
ダニエルF 14年

これは、grepコマンドに-Rが実装されていないクライアントを対象としていることが気に入っています。
Aviose 14

:あなたが印刷され、一致する行とファイル名をしたい場合は、execのような作り... -exec bash -c 'grep -r "mystring" {} && echo {}' \;
Donnリー

grepを直接使用した場合の相対的なパフォーマンスはどうですか?
ジョナサン

19

私のデフォルトのコマンドは

grep -Rin string *

キャピトル 'R'をls使用します。これは再帰的に使用するためです。grepは両方を受け入れるため、使用しない理由はありません。

編集:HVNSweetingに従って、明らか-Rにシンボリックリンクをたどります-r


1
隠しファイルも検索するには、実行しますshopt -s dotglob-s「セット」として覚えておいてください)。ファイルを削除するときは注意してください。dotglobが有効になっている場合rm -r *、現在のディレクトリ内のすべてが削除されますが、一致するためにその上のディレクトリ削除されます..。dotglobを無効にするには、shopt -u dotglob( "unset")を使用します。ただし、変更は一時的なものであり、現在のシェルにのみ適用されます。
レーケンシュタイン

これを忘れました。1行1行に設定する方法はありますか?shopt -s dotglob & <grep cmd> & shopt -y dotglobもっと便利なだけのようなもの?このように、リセットを心配する必要はありません
-user606723

また、grep -Rin string .これらのケースのほとんどで使用するのがおそらく簡単です。*を使用するのは、より自然に来るようだからです。
-user606723

1
再帰的なgrepを実行する場合、「。」から開始できます。の代わりに "*"。ドットグロブは必要ありません。
ミチャウシュラージェル

1
これに賛成票を投じ、マンページで言及されていないことの1つはR、シンボリックリンクに従うことであり、rそうではない
-HVNSweeting

12

何か新しいことを試してみたいと思うなら、試してみてくださいack。現在のディレクトリを再帰的に検索するコマンドstringは次のとおりです。

ack string

インストールは非常に簡単です。

curl http://betterthangrep.com/ack-standalone > ~/bin/ack && chmod 0755 !#:3

(既にディレクトリ~/binを取得しており、できればにある場合PATH)。


2
または、apt-get install ack-grep(および.bashrcにエイリアスack = ack-grepを追加)
-markijbema

chmodコマンドの最後のパラメーターは何をしますか?それらは特定のものですchmodか、それともbash関連!#:3ですか(部分)?
エリオットダーフィンク14年

それはバッシュの使用だ@ElliottDarfink 履歴機能を - !あるイベント指示子。繰り返しを避けるために非常に強力です。!#:3これまでのコマンドラインの3番目のトークン、つまり~/bin/ackこの場合を参照します。
コンラッドルドルフ14年

4

コマンドrgrepはこのようなニーズ専用です

利用できない場合は、次のように取得できます

mkdir -p ~/bin
cd ~/bin
wget http://sdjf.esmartdesign.com/files/rgrep
chmod +x rgrep

上記のように、デフォルトのgrepオプションに直接設定できます。

私は個人的に使用します

[[  ${#args} -lt 5 && "${args//[[:space:]]/}" == "-i" ]] && args="-Hin"
args="${args:--Hns} --color=auto"

関連トピック:rgrepを常に色付きで使用する方法


rgrepは、Ubuntuにデフォルトでインストールされるgrepパッケージによって提供されます。
カレル

2

アップデート2:

問題を使用findしてgrep修正する次のコマンド行:

$ find path_to_search_in -type f -exec grep -in searchString {} 2> /dev/null +

--color=<always or auto> カラー出力の場合:

$ find path_to_search_in -type f \
            -exec grep --color=always -in searchString {} 2>/dev/null +

例:

$ find /tmp/test/ -type f -exec grep --color=auto -in "Search string" {} 2>/dev/null +

以下のスナップショットで実行する例: snap1


更新1:

次のコードを試すことができます。あなたの中の関数として.bashrcまたは.bash_aliasesまたはスクリプトで:

wherein () 
{ 
    for i in $(find "$1" -type f 2> /dev/null);
    do
        if grep --color=auto -i "$2" "$i" 2> /dev/null; then
            echo -e "\033[0;32mFound in: $i \033[0m\n";
        fi;
    done
}

使用法: wherein /path/to/search/in/ searchkeyword

例:

$ wherein ~/Documents/ "hello world"

(注:@enzotibによる以下のコメントで示唆されているように、これは名前にスペースを含むファイル/ディレクトリでは機能しません。)


元の投稿

文字列を検索し、検索文字列でその行だけを出力するには:

$ for i in $(find /path/of/target/directory -type f); do \
    grep -i "the string to look for" "$i"; done

例えば:

$ for i in $(find /usr/share/applications -type f); \
    do grep -i "web browser" "$i"; done

検索文字列を含むファイル名を表示するには:

$ for i in $(find /path/of/target/directory -type f); do \
    if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;

例えば:

$ for i in $(find /usr/share/applications -type f); \
    do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \
    fi; done;

スペースを含むファイル名では失敗します。失敗は、stderrが表示されないという事実によって隠されています。
-enzotib

...それはまだ指定された関数で未解決だということを指摘してくれてありがとう@enzotib ..私はしかし、他のワンライナーを追加しました...
精密

これで、答えは@dmityugovのそれに似ています。
-enzotib

はい、しかしその意味で、このページのほとんどの回答は、... grepを使用するサブセットの次に、... を使用する点で似ていますが、異なるスイッチと微調整を個別の回答として受け入れる場合は、おそらく私もここに収まるでしょう。最後の更新では、検索で必要なことを実行します。検索キーと行番号を含む行を含むファイル名。読みやすくするための色付きの出力とエラーフィルターfindgrep
正確な

2

grepGNUまたはBSD

grepツールを使用して-r、次のようなパラメーターを使用して現在のフォルダーを再帰的に検索できます。

grep -r "pattern" .

注:-r-サブディレクトリを再帰的に検索します。

特定のファイル内を検索するには、次のようなグロビング構文を使用できます。

grep "class foo" **/*.c

注:グロビングオプション**)を使用すると、特定の拡張子またはパターンですべてのファイルが再帰的にスキャンされます。この構文を有効にするには、次を実行しますshopt -s globstarまた**/*.*、すべてのファイル(非表示および拡張子なし)またはその他のパタ​​ーンに使用できます。

引数が長すぎるというエラーがある場合は、検索を絞り込むか、次のようなfind構文を使用してください。

find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'

または、を使用しますripgrep

ripgrep

大きなプロジェクトや大きなファイルで作業している場合は、ripgrep代わりに次のように使用する必要があります。

rg "pattern" .

GitHubプロジェクトページでドキュメント、インストール手順、またはソースコードをチェックアウトします

それはのような他のツールよりもはるかに高速だGNU / BSD grepucgagsiftackptそれは上に構築されているため、または類似の錆の正規表現エンジンは非常に高速な検索を行うために、有限オートマトン、SIMDと積極的なリテラル最適化を使用しています。

.gitignoreファイルで指定された無視パターンをサポートしているため、単一のファイルパスを複数のグロブパターンと同時に照合できます。


次のような共通パラメーターを使用できます。

  • -i -インセンシティブ検索。
  • -I -バイナリファイルを無視します。
  • -w -単語全体を検索します(部分的な単語一致の反対)。
  • -n -試合の行を表示します。
  • -C/ --context(例-C5)-コンテキストを増やすため、周囲のコードが表示されます。
  • --color=auto -一致するテキストをマークアップします。
  • -H -テキストが見つかったファイル名を表示します。
  • -c-一致する行の数を表示します。と組み合わせることができます-H

1

私はこれを非常に過小評価されているコマンドであるxargsを使用して行います

find ./ -type f -print0 | xargs -0 grep 'string_you_are_looking_for'

find ./は、現在のフォルダー内のすべてのファイルの再帰的なリストを提供し、それらを各ファイルでgrepコマンドを実行するxargsにパイプします


4
オプションto およびオプションto xargsなしで使用する ことは非推奨であり、スペースを含むファイル名では失敗します。-print0find-0xargs
エンゾチブ

@enzotibあなたが提案したように答えを編集しました。-確認してください。編集と修正が必要な場合は、あなたが再編集できます。ありがとう
αғsнιη

1
@KasiyA:今は大丈夫です。私の下票を削除しました。
enzotib

0

ここにはたくさんの答えがあることは知っていますが、ファイルを検索するときに他の制限を追加したい場合の代替案があります:

find . -type f -exec grep --quiet string_to_look_for {} ';' -print

これgrepは、結果が見つかった場合は0を返し、それ以外の場合は1を返すため、機能します。たとえば、1 MBのサイズ何か含むファイルを見つけることができます。

find . -type f -exec grep --quiet string_to_look_for {} ';' -size 1M -print

複数の要件については、おそらく-OGNU grepに存在するオプティマイザーフラグを使用する必要があります。


0

C、CPPコードで検索するスクリプト(コード内検索):

#!/bin/sh

find . \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" \) -type f -print0 | xargs -0 grep --color -n "$1"

つかいます:

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