どうすれば再帰的にgrepできますか?


1682

grepすべてのディレクトリとサブディレクトリを再帰的にするにはどうすればよいですか?

find . | xargs grep "texthere" *

110
@ TC1悲しいことは、grep自体が質問(少なくともGNU grep)に答えることができるということです:grep --help | grep recursive
Frank Schmitt 2013年

7
grepを頻繁に使用して再帰的な検索を行う場合(特に、多くのファイル/ディレクトリの除外を手動で行う場合)、ack(非常にプログラマーフレンドリーなgrepの代替)が役立つことがあります。
Nick McCurdy 2013年

19
実際、私が職場で使用しているSolarisボックスでは、-rも--recursiveも機能しません。また、grepのmanページには、再帰的な記述はありません。私は自分自身を見つけてxargsする必要がありました。
ベン・

8
agは、今これを行うための私のお気に入りの方法ですgithub.com/ggreer/the_silver_searcher
dranxo

1
grep -rin xlsx *.plRedhat Linuxでは動作しません。「一致しません」というエラーが表示されます。
Bulrush

回答:


2507
grep -r "texthere" .

最初のパラメーターは検索する正規表現を表し、2番目のパラメーターは検索するディレクトリを表します。この場合、.は現在のディレクトリを意味します。

注:これはGNU grepで機能し、Solarisなどの一部のプラットフォームでは、従来の実装ではなく、GNU grepを使用する必要があります。Solarisの場合、これはggrepコマンドです。


39
注:「grep -r」は新しいgrepsでのみ機能します。AIX 5.3たとえば、付属のgrepでは機能しません。
2013

110
シンボリックリンクを追跡するには、grep -Rを使用します。
Eloff、2013

53
「-i」を指定すると大文字と小文字が区別されなくなり、「-n」には一致した各結果の行番号も含まれます。
Sadegh、2015年

24
また、正規表現ではなく固定文字列を探している場合は、-Fオプションを使用してください。正規表現パーサーを呼び出さないことで、時間を大幅に節約できます。多くのファイルを検索する場合に非常に便利です。
ジェフ

6
エイリアスrgrep = 'grep -r'
totten

679

必要なファイルの拡張子またはパターンがわかっている場合は、--includeオプションを使用する方法もあります。

grep -r --include "*.txt" texthere .

で除外するファイルについて言及することもできます--exclude

Ag

コードを頻繁に検索する場合、Ag(The Silver Searcher)はgrepのはるかに高速な代替手段であり、コードの検索用にカスタマイズされています。たとえば、デフォルトでは再帰的であり.gitignore、にリストされているファイルとディレクトリを自動的に無視するため、同じ厄介な除外オプションをgrepまたはfindに渡さなくてもかまいません。


3
LinuxとCygwinに付属のgrepでうまく機能しますが、AIXに付属のgrepではうまく機能しません。
2013年

1
@KrzysztofWolny:=Ubuntu では、 ``の代わりにうまく機能します。PS:これはバッククォートされたスペースであるはずですが、SOマークダウンパーサーは失敗しました。
Dan Dascalescu、2014

4
@DanDascalescu私grepはAgではなく、に賛成しました。ご存知のように:)
Bernhard

1
再帰的に検索するときにディレクトリを除外するオプションはありますか?
トムテイラー

Windows cygwinは二重引用符が好き--include "*.txt" --include "*.TXT"
ボブスタイン

127

また:

find ./ -type f -print0 | xargs -0 grep "foo"

しかしgrep -r、より良い答えです。


14
または、ファイル名のスペースについて心配したくない場合はfind . -type f -exec grep "foo" '{}' \;、サポートされている場所でうまく機能します。
Edd Steel

4
xargsを介してgrepにパイプ検索を行う場合、および固定文字列のみ(つまり、正規表現ではない)を検索する場合は、grep -Fオプションを呼び出すとメリットがあるため、grepは正規表現エンジンをロードしません。呼び出しごとに。多くのファイルがある場合、それははるかに速くなります。
ジェフ

2
見つける -type f -exec grep -Hu "foo" {} \; それはファイル名を与えるので私が使用するものです。
ウェス


1
find ./ -type f -print0 | xargs -0 grep "foo"
aehlke 14

118

私は常に使用しています(GoWのある Windowsでも-WindowsのGnuでも):

grep --include="*.xxx" -nRHI "my Text to grep" *

これには次のオプションが含まれます。

--include=PATTERN

一致するファイルのみを検索するディレクトリで再帰しますPATTERN

-n, --line-number

出力の各行の前に、入力ファイル内の行番号を付けます。

(注:phuclv-nパフォーマンス大幅に低下させるコメントを 追加するため、そのオプションをスキップすることができます)

-R, -r, --recursive

各ディレクトリの下のすべてのファイルを再帰的に読み取ります。これは-d recurseオプションと同等です。

-H, --with-filename

一致ごとにファイル名を出力します。

-I     

一致するデータが含まれていないかのようにバイナリファイルを処理します。
これは--binary-files=without-matchオプションと同等です。

また、大文字と小文字を区別しない結果が必要な場合は、' i'(-nRHIi)を追加できます。

私は得ることができます:

/home/vonc/gitpoc/passenger/gitlist/github #grep --include="*.php" -nRHI "hidden" *
src/GitList/Application.php:43:            'git.hidden'      => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
src/GitList/Provider/GitServiceProvider.php:21:            $options['hidden'] = $app['git.hidden'];
tests/InterfaceTest.php:32:        $options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
vendor/klaussilveira/gitter/lib/Gitter/Client.php:20:    protected $hidden;
vendor/klaussilveira/gitter/lib/Gitter/Client.php:170:     * Get hidden repository list
vendor/klaussilveira/gitter/lib/Gitter/Client.php:176:        return $this->hidden;
...

Gowは有望に見えます-私が使用しているGNU Windowsユーティリティより新しいです。今すぐ試す...
Radim Cernej、2016年

ここで最後の文字*の意味は何ですか?
lorniper

2
@lorniperは、シェルに現在のディレクトリ内のすべてのファイルとフォルダーを選択させ、次にgrepをそれらのファイルと(-Rオプションにより再帰的に)フォルダーに適用させます。
VonC

2
@lorniper Noy正確:*または.globパターン(シェルによって解釈されます):unix.stackexchange.com/a/64695/7490。' .'は、ドットファイルまたはドットフォルダも選択します(など.git/
VonC

以前はいつも使用してgrep -rnIいましたが、-nパフォーマンスが大幅に低下することを知ったので、本当に必要なときに使用するだけです。通常は使用します-rI
phuclv

25

POSIXシステムでは、あなたが見つからない-rため、パラメータをgrep、あなたgrep -rn "stuff" .の意志は実行されませんが、あなたが使用している場合find、コマンドをそれは以下となります。

find . -type f -exec grep -n "stuff" {} \; -print

で合意したSolarisHP-UX


{} \の意味は何ですか。-それぞれ印刷?
user1169587

3
では-execオプション-シンボルは{}、現在で見つかったファイル名への参照ですfind(私たちが見つけたファイル名で何かを行うことです)ツールは、また、-execオプションはで終了する必要があり;、これがすべてであるので、(EXECコマンドの終了マーク)のシンボルが、シェルで実行しているそのシンボルはエスケープする必要があります。最後に-printオプションを使用すると、findツールは検出されたファイル名を画面に出力できます。
ルーク

19

グロビング **

使用はgrep -r機能しますが、特に大きなフォルダーでは、やり過ぎになる場合があります。

より実用的な使用法として、ここではグロビング構文**)を使用する構文を示します。

grep "texthere" **/*.txt

これは、パターンが選択されたパターンを持つ特定のファイルのみを把握します。Bash +4zshなどのサポートされているシェルで機能します。

この機能をアクティブにするには、次を実行しますshopt -s globstar

参照:Linuxで特定のテキストを含むすべてのファイルを見つけるにはどうすればよいですか?

git grep

Gitバージョン管理下のプロジェクトでは、次を使用します。

git grep "pattern"

はるかに速いです。

ripgrep

大規模なプロジェクトの場合、最も速いgreppingツールはripgrep、デフォルトでファイルを再帰的にgrepsすることです。

rg "pattern" .

これは、有限オートマトン、SIMD、および積極的なリテラル最適化を使用して検索を非常に高速にするRustの正規表現エンジンの上に構築されています。詳細な分析はここで確認してください。


3
git grepの提案に感謝します-それは非常に便利で、私はそれについて知りませんでした!
Basya

2
ripgrepの提案に感謝します。それはずっと速いです。
何をクールになる

11

の特定の名前filespath再帰的に含むwith を検索stringするには、以下のコマンドを使用しますUNIX

find . | xargs grep "searched-string"

のためにLinux

grep -r "searched-string" .

UNIXサーバー上のファイルを見つける

find . -type f -name file_name

Linuxサーバーでファイルを検索する

find . -name file_name

11

ファイル名だけでも役に立ちます

grep -r -l "foo" .

10

シンボリックリンクではなく、実際のディレクトリのみをたどる場合は、

grep -r "thingToBeFound" directory

シンボリックリンクと実際のディレクトリをたどる場合(無限再帰に注意してください)、

grep -R "thing to be found" directory

再帰的にgrepを実行しようとしているため、次のオプションも役立つ場合があります。

-H: outputs the filename with the line

-n: outputs the line number in the file

したがって、現在のディレクトリまたは任意のサブディレクトリでDarth Vaderを含むすべてのファイルを検索し、ファイル名と行番号をキャプチャしたいが、再帰がシンボリックリンクをたどらないようにするには、コマンドは次のようになります。

grep -rnH "Darth Vader" .

ディレクトリでcatという単語のすべての言及を検索する場合

/home/adam/Desktop/TomAndJerry 

そしてあなたは現在ディレクトリにいます

/home/adam/Desktop/WorldDominationPlot

ファイル名をキャプチャし、文字列 "cats"のインスタンスの行番号はキャプチャしません。また、再帰がシンボリックリンクを見つけた場合、それをたどります。次のいずれかを実行します。

grep -RH "cats" ../TomAndJerry                   #relative directory

grep -RH "cats" /home/adam/Desktop/TomAndJerry   #absolute directory

ソース:

「grep --help」を実行する

シンボリックリンクの簡単な紹介、この回答を読んでいて、それらへの私の参照で混乱した人のために:https : //www.nixtutor.com/freebsd/understanding-symbolic-links/


すばらしい答えです。追加のスイッチ(-rnh)は非常に役立つので、提案していただきありがとうございます。
semtex41

8

agはこれを実行するための私のお気に入りの方法ですgithub.com/ggreer/the_silver_searcher。基本的にはackと同じですが、いくつかの最適化が追加されています。

ここに短いベンチマークがあります。各テストの前にキャッシュをクリアします/ubuntu/155768/how-do-i-clean-or-disable-the-memory-cacheを参照

ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time grep -r "hey ya" .

real    0m9.458s
user    0m0.368s
sys 0m3.788s
ryan@3G08:$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ack-grep "hey ya" .

real    0m6.296s
user    0m0.716s
sys 0m1.056s
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ag "hey ya" .

real    0m5.641s
user    0m0.356s
sys 0m3.444s
ryan@3G08$ time ag "hey ya" . #test without first clearing cache

real    0m0.154s
user    0m0.224s
sys 0m0.172s


6

ディレクトリ構造からすべてのファイルの特定のコンテンツを探している場合はfind、何をしているのかがより明確であるため、次のように使用できます。

find -type f -exec grep -l "texthere" {} +

なお、-l(Lのdowncase)は、テキストを含むファイルの名前を示します。代わりに試合そのものを印刷したい場合は、削除してください。または-H、一致と一緒にファイルを取得するために使用します。まとめると、他の選択肢は次のとおりです。

find -type f -exec grep -Hn "texthere" {} +

どこに-n行番号を出力します。


2
find不必要な使用とxargs、withの+代わりの使用の両方を回避するための唯一のソリューションであるとの投票により、大量の不要なプロセスの起動を回避します。:-)\;-exec
ShadowRanger、2016年

6

これは私の現在のマシンで私のケースで機能したものです(Windows 7ではgit bash):

find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"

スペースのあるパスの-print0と-0は常に忘れます。

編集:私の優先ツールは、代わりにripgrepです:https : //github.com/BurntSushi/ripgrep/releases。これは本当に高速で、デフォルトが優れています(デフォルトの再帰のように)。私の元の答えと同じ例ですが、ripgrepを使用しています:rg -g "*.cs" "content pattern"


4

grep -r "texthere" . (終了時の通知期間)

(^ credit:https : //stackoverflow.com/a/1987928/1438029


明確化:

grep -r "texthere" /すべてのディレクトリとサブディレクトリを再帰的にgrepします

grep -r "texthere" .これらのディレクトリとサブディレクトリを再帰的にgrepします

grep再帰的

grep [options] PATTERN [FILE...]

【オプション】

-R, -r, --recursive

各ディレクトリの下のすべてのファイルを再帰的に読み取ります。

これは-d recurseor --directories=recurseオプションと同等です。

http://linuxcommand.org/man_pages/grep1.html

grepヘルプ

$ grep --help

$ grep --help |grep recursive
  -r, --recursive           like --directories=recurse
  -R, --dereference-recursive

代替案

ackhttp://beyondgrep.com/

aghttp://github.com/ggreer/the_silver_searcher


4

2018年には、あなたが使用したいripgrepか、the-silver-searcher彼らは道より高速な代替よりもあるため。

以下は、第1レベルのサブディレクトリが336個あるディレクトリです。

% find . -maxdepth 1 -type d | wc -l
     336

% time rg -w aggs -g '*.py'
...
rg -w aggs -g '*.py'  1.24s user 2.23s system 283% cpu 1.222 total

% time ag -w aggs -G '.*py$'
...
ag -w aggs -G '.*py$'  2.71s user 1.55s system 116% cpu 3.651 total

% time find ./ -type f -name '*.py' | xargs grep -w aggs
...
find ./ -type f -name '*.py'  1.34s user 5.68s system 32% cpu 21.329 total
xargs grep -w aggs  6.65s user 0.49s system 32% cpu 22.164 total

OSXでは、これにより次のものがインストールされripgrepますbrew install ripgrep。これがインストールしますsilver-searcherbrew install the_silver_searcher


これを頻繁に行う必要がある場合は速度が重要ですが、ほとんどの場合、これを行うのはせいぜい年に数回だけです。最新の洗練されたサードパーティのjujuツールdu jourをインストールするのはやり過ぎであり、1978年以降あまり変更されていないソリューションは関係なく知っておくと役に立ちます。
Tripleee

プログラマが1年に数回だけソースツリー内のテキストを検索することは非常にありがたくありません。しかし、使いやすさの観点からもrg、再帰的なgrepコマンドを最初からやり直すことにかなりの優位性があります。使用rgrg foo。UNIXツールの使用:find . | xargs grep foo。また、ファイルに引用が含まれている場合は、を使用する必要がありますfind . -print0 | xargs -0 grep foo。これを年に数回使用すると、覚えているでしょうか?
hughdbrown 2018年

1
あなただ忘却find . -type f -exec grep 'regex' {} +確かにあなたはどんな規則的にこれらのツールを使用している場合は覚えやすいです。しかし、おそらくあなたは、実行する必要がありますctagsまたはetagsあなたが頻繁にものを見つける必要がある場合は、とにかく自分のソースツリーに。
Tripleee、2018年

私はripgrepを使用していますが、それは素晴らしいことです。しかし、シルバーサーチャーはプログラマーにとって素晴らしいものです。+1
Matt

3

私のIBM AIXサーバー(OSバージョン:AIX 5.2)では、以下を使用します。

find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \; 

これにより、次のようにファイル内のパス/ファイル名と相対行番号が出力されます。

./inc/xxxx_x.h

2865:/ **説明:stringYouWannaFind * /

とにかく、それは私のために働きます:)


3

以下は、String再帰的にUnixLinux環境を検索するコマンドです。

以下のためのUNIXコマンドです。

find . -name "string to be searched" -exec grep "text" "{}" \;

以下のためのLinuxコマンドです。

grep -r "string to be searched" .

2

利用可能なフラグのリストについては:

grep --help 

現在のディレクトリにある正規表現テキストのすべての一致を、対応する行番号とともに返します。

grep -rn "texthere" .

ルートディレクトリから開始し、対応する行番号を付けて大文字と小文字を区別せずにtexthereに一致するものをすべて返します。

grep -rni "texthere" /

ここで使用されるフラグ:

  • -r 再帰的
  • -n 出力に行番号を出力する
  • -i 大文字小文字を区別しない

1

これはあなたが書こうとしていることだと思います

grep myText $(find .)

これは、grepでヒットしたファイルを見つけたい場合に役立ちます。

grep myText $(find .) | cut -d : -f 1 | sort | uniq

それは非常に直感的です:例:grep -i acc $(find。-name "execution *。*")
Yu Shen

1

ここに2セントを投げます。他の人がすでに述べたように、grep -rはすべてのプラットフォームで機能するわけではありません。これはばかげて聞こえるかもしれませんが、私はいつもgitを使用しています。

git grep "texthere"

ディレクトリがステージングされていなくても、ステージングしてgit grepを使用するだけです。


0

find . -type f | xargs grep whatever検索で一致するファイルが多すぎる場合、解決策の種類によって「引数リストが長くなります」エラーが発生することに注意してください。

最善の策ですgrep -rが、それが利用できない場合は、find . -type f -exec grep -H whatever {} \;代わりに使用してください。


えっ? xargs特に「引数リストが長すぎる」問題の回避策です。
tripleee 2015

2
まあ、いいえ-xargsは特に引数のパイプをarglistに変換するためのものですが、はい、-sや-Lと組み合わせて使用する場合、最新のxargsは複数のコマンド呼び出しに分割することで非常に長いarglistを処理できますが、デフォルトではそのように構成されていません(上記の応答には含まれていません)。例:find . -type f | xargs -L 100 grep whatever
m.thome 2015

それはどのプラットフォームにありますか? POSIXxargsは、この動作をそのまま使用できるように標準化されています。xargsユーティリティは、コマンドラインが呼び出されたときに、引数と環境リストの組み合わせが{ARG_MAX} -2048バイトを超えないように、コマンドラインの長さを制限します。」
tripleee 2015

うーん。これに基づいて、GNUドキュメントはposixよりも明確ではなく、このステートメントを作成する原因となったマシンにアクセスできなくなりましたが、現在の実装では元の解釈を確認できません。もちろん、再帰的なgrepが利用可能な場合でも望ましいですが、xargsレシピを回避する理由はほとんどありません(ただし、grepの最後の呼び出しが単一のファイル名のみを渡されないように、grepに-Hを使用してください)。
m.thome 2015

0

ちょうど面白くするために、@ christangrantの回答が多すぎて入力できない場合は、*。txtファイルをすばやく簡単に検索します。

grep -r texthere .|grep .txt


0

これは、指定されたフォルダー($ 1)のすべてのサブフォルダーをトラバースし、指定grepされたファイル($ 2)で指定された文字列($ 3)を検索する再帰(bashおよびshで軽くテストされた)関数です。

$ cat script.sh
#!/bin/sh

cd "$1"

loop () {
    for i in *
    do
        if [ -d "$i" ]
        then
            # echo entering "$i"
            cd "$i"
            loop "$1" "$2"
        fi
    done

    if [ -f "$1" ]
    then
        grep -l "$2" "$PWD/$1"
    fi

    cd ..
}

loop "$2" "$3"

実行して出力例:

$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename

-2
The syntax is:
cd /path/to/dir
grep -r <"serch_word name"> .

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