web-dev-qa-db-ja.com

再帰的にgrepするにはどうすればいいですか?

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

find . | xargs grep "texthere" *
1532
wpiri
grep -r "texthere" .

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

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

2304
Vinko Vrsalovic

あなたが望むファイルの拡張子やパターンを知っているなら、他の方法は--includeオプションを使うことです:

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

--excludeを使って除外するファイルに言及することもできます。

Ag

コードを頻繁に検索する場合は、 Ag(The Silver Searcher) がgrepに代わるはるかに高速な方法であり、コード検索用にカスタマイズされています。たとえば、デフォルトでは再帰的で、.gitignoreにリストされているファイルおよびディレクトリを自動的に無視するので、grepまたはfindに同じ面倒な除外オプションを渡し続ける必要はありません。

623
christangrant

また:

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

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

120
Kurt

私は今いつも使っています( GoW - WindowsのGnu を使っているWindowsでも):

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

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

--include=PATTERN

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

-n, --line-number

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

(注: phuclv adds コメント内の that -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;
...
107
VonC

POSIXシステムでは、grep-rパラメータが見つからず、grep -rn "stuff" .が実行されませんが、findコマンドを使用すると、次のようになります。

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

SolarisHP-UXが同意しました。

21
rook

globbing **

grep -rを使用するとうまくいきますが、特に大きなフォルダではやり過ぎるかもしれません。

より実用的な使用法のために、 グロブ構文**)を使用する構文は、以下のとおりです。

grep "texthere" **/*.txt

これはパターン選択されたパターンで特定のファイルだけをgrepします。 Bash + 4 または zsh などのサポートされているシェルで動作します。

この機能を有効にするには、shopt -s globstarを実行します。

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

git grep

Gitバージョン管理下にあるプロジェクトの場合は、次のようにします。

git grep "pattern"

これははるかに速いです。

ripgrep

大規模なプロジェクトでは、最速のgreppingツールは ripgrep で、デフォルトで再帰的にファイルをgrepsします。

rg "pattern" .

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

16
kenorb

特定のfilesを再帰的に含むpathstringの名前を見つけるには、以下の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
chim

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

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" .

あなたがディレクトリ内のWord猫のすべての言及を見つけたい場合

/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/

9
SarcasticSully

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

これが短いベンチマークです。各テストの前にキャッシュをクリアします(cf https://askubuntu.com/questions/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
8
dranxo

これは私の現在のマシンで私のケースでうまくいったものです(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"

6
arkod

ディレクトリ構造からすべてのファイルで特定のコンテンツを探す場合は、findを使用することができます。

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

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

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

-nは行番号を表示します。

6
fedorqui

これはうまくいくはずです。

grep -R "texthere" *
5
sumit kumar

grep -r "texthere" .(最後の通知期間)

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


説明:

grep -r "texthere" /(再帰的にgrep all ディレクトリおよびサブディレクトリ)

grep -r "texthere" .(再帰的にgrep theseディレクトリとサブディレクトリ)

再帰的grep

grep [options] PATTERN [FILE...]

[オプション]

-R, -r, --recursive

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

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

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

grepヘルプ

$ grep --help

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

代替案

ackname__( http://beyondgrep.com/ /)

agname__( http://github.com/ggreer/the_silver_searcher

4
Geoffrey Hale

私のIBM AIXサーバー(OSバージョン:AIX 5.2)では、以下を使用してください。

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

これは、ファイルのパス/ファイル名と相対行番号を次のように表示します。

./inc/xxxx_x.h

2865:/ **説明:stringYouWannaFind * /

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

3
user3606336

以下は、StringおよびUnix環境でLinuxを再帰的に検索するためのコマンドです。

UNIXコマンドの場合:

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

Linuxコマンドの場合:

grep -r "string to be searched" .

私はこれがあなたが書き込もうとしているものであると思います

grep myText $(find .)

grep hitのファイルを見つけたい場合、これは他の何か役に立つかもしれません

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

2018年に、あなたはripgrepまたはthe-silver-searcherを使いたいのです。なぜならそれらは他のものよりずっと速いからです。

これは、336の第1レベルのサブディレクトリを持つディレクトリです。

% 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では、これはripgrepbrew install ripgrepをインストールします。これはsilver-searcherbrew install the_silver_searcherをインストールします。

2
hughdbrown

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

grep --help 

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

grep -rn "texthere" .

texthere に対応するすべてのマッチをルートディレクトリから始めて対応する行番号で返します。

grep -rni "texthere" /

ここで使われているフラグ:

  • -r再帰
  • -n行番号を出力付きで表示
  • -iは大文字と小文字を区別しません
2
JSON C11

Findによって一致するファイルが多すぎると、find . -type f | xargs grep whatever種類の解決策が "Argument list to long"エラーに遭遇することに注意してください。

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

1
m.thome

ちょっとした楽しみのために、@ christangrantの答えがタイプするには多すぎるなら* .txtファイルの迅速で汚い検索

grep -r texthere .|grep .txt

1
PJ Brunet

これは、与えられたフォルダ($ 1)のすべてのサブフォルダをトラバースし、与えられたファイル($ 2)の中で与えられた文字列($ 3)をgrepで検索する再帰(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
0
James Brown