特定のファイルをgrepしないようにするには、grep --exclude /-include構文を使用します


780

foo=ディレクトリツリーのテキストファイルで文字列を探しています。それは一般的なLinuxマシン上にあり、私はbashシェルを持っています:

grep -ircl "foo=" *

ディレクトリには、 "foo ="に一致する多くのバイナリファイルもあります。これらの結果は関連性がなく、検索が遅くなるため、grepでこれらのファイル(主にJPEGおよびPNG画像)の検索をスキップするようにします。どうすればいいですか?

--exclude=PATTERN--include=PATTERNオプションがあることはわかっていますが、パターンの形式は何ですか?grepのmanページにはこう書かれています:

--include=PATTERN     Recurse in directories only searching file matching PATTERN.
--exclude=PATTERN     Recurse in directories skip file matching PATTERN.

上の検索grepを含める含め除外のgrep除外GREPおよび変異体は、関連する何かを見つけることができませんでした

特定のファイルでのみgrepを実行するより良い方法がある場合は、それで十分です。問題のあるファイルを移動することはできません。特定のディレクトリだけを検索することはできません(ディレクトリ構造はすべての場所にあり、非常に混乱しています)。また、何もインストールできないため、一般的なツール(grepや推奨されるfindなど)を使用する必要があります


13
参考までに、使用された引数:-cファイル内の一致をカウント-i大文字と小文字を区別せず-l一致するファイルのみを表示-r再帰的
-Piskvorが建物を去った

68
svn dirsを除外するより速い方法は--exclude-dir=.svnなので、grepはそれらにまったく入りません
orip

25
1.グロブの周りの引用符の欠如に注意してください:--exclude = ' 。{png、jpg}'は動作しません(少なくとも私のGNU grepバージョンでは)。グロブでは{}をサポートしていません。上記は '--exclude = .png --exclude = *。jpg'にシェル展開されています(CWDでファイルが一致しないと仮定します-通常、ファイル名を '--exclude ='で始めないため、ほとんどありません)。 grepは大丈夫です。2. --excludeはGNU拡張機能であり、POSIXのgrepの定義の一部ではないため、これを使用してスクリプトを作成する場合は、GNU以外のシステムでは必ずしも実行されないことに注意してください。
ijw

2
exclude-dirの使用例:grep -r --exclude-dir=var "pattern" .
Tisch

回答:


767

シェルグロビング構文を使用します。

grep pattern -r --include=\*.{cpp,h} rootdir

の構文--excludeは同じです。

スターはバックスラッシュでエスケープされ、シェルによって展開されないようになっていることに注意してください(などの引用符--include="*.{cpp,h}"も同様に機能します)。あなたがパターンと一致したことを、現在の作業ディレクトリ内のファイルがあった場合のようにそれ以外の場合は、コマンドラインは何かに拡大するgrep pattern -r --include=foo.cpp --include=bar.h rootdirだけの名前のファイルを検索することになる、foo.cppbar.hあなたが望んでかなり可能性がされていません、。


8
私はなぜ知らないが、私はこのようなパターンなどが引用した:grep pattern -r --include="*.{cpp,h}" rootdir
topek

6
@topek:良い点-現在のディレクトリに.cpp / .hファイルがある場合、シェルはgrepを呼び出す前にグロブを展開するのでgrep pattern -r --include=foo.cpp --include=bar.h rootdir、ファイルのみを検索するようなコマンドラインが作成されます。名前付きfoo.cppまたはbar.h。現在のディレクトリのグロブに一致するファイルがない場合、シェルはグロブをgrepに渡し、grepはそれを正しく解釈します。
Adam Rosenfield、2011

6
グロブはファイル名の照合のみに使用されていることに気づきました。ディレクトリ全体を除外するには、--exclude-dirオプションが必要です。同じルールが適用されます。パスではなく、ディレクトリのファイル名のみが一致します。
KrzysztofJabłoński15年

3
--include後に動作しないようです--exclude。ライブラリやスワップファイルなどを無視してコードを検索するために使用するandのalias長いリストをgrepする必要があることを除いて、試しても意味がないと思います。私が望んでいただろう、私は制限できるよう、仕事と私にだけ、無視しているようだと.fooというファイルはありませんすべてのものが含まれます。との動作を入れ替えますが、悲しいかな、それは私にとっては役に立ちません。--exclude--exclude-dirgrep -r --exclude='*.foo' --include='*.bar'alias--include='*.bar'--include--include--excludealias
Michael Scheper 16

1
このルールを取得するために誰かの心をどのように読むことができるでしょうかPATTERN。30分私は彼らがそこで何を待っているのかについての説明を見つけることができません
アルカディ

221

バイナリファイルをスキップするだけの場合は、-I(大文字のi)オプションを確認することをお勧めします。バイナリファイルは無視されます。私は次のコマンドを定期的に使用しています。

grep -rI --exclude-dir="\.svn" "pattern" *

それは再帰的に検索し、バイナリファイルを無視し、Subversionの隠しフォルダーを調べません。私は、職場で自分のボックスに「grepsvn」というエイリアスを設定しています。


1
おかげで、これは私が遭遇した他のいくつかのシナリオで非常に役立ちます。
Piskvorは、

25
--exclude-dirどこでも利用できるわけではありません。GNU grep 2.5.1で動作している私のRHボックスにはそれがありません。
gcb

--exclude-dir利用できないときに何を使用するかについての提案はありますか?私のすべての試みで--exclude、法案に合うようには見えません。
JMTyler 2014年

GNUからいつでも最新のgrepソースをダウンロードして、 'configure; 作る; sudo make install '。これは、Macまたは古いLinunxディストリビューションで最初に行うことの1つです。
ジョナサンハートレー

3
まさに私が必要としたもの。実はgitを使っています。だから、--exclude-dir="\.git"。:-)
IonicăBizău

66

まさにこれらの状況のた​​めに設計されたackをご覧ください。あなたの例

grep -ircl --exclude=*.{png,jpg} "foo=" *

としてackで行われます

ack -icl "foo="

ackはデフォルトでバイナリファイルを検索することはなく、-rはデフォルトでオンになっているためです。CPPファイルとHファイルのみが必要な場合は、

ack -icl --cpp "foo="

よさそうだ、次回はスタンドアロンのPerlバージョンを試してみるよ、ありがとう。
Piskvorは、

5
いい電話、私はもはやACKなしでは生きられない。
チャンス

1
stackoverflow.com/questions/667471/…-grepを実行している場合、これによりWindowsでackを取得できます。
TamusJRoyce

@チャンス多分あなたはちょうどUbuntuでsilversearcher-agが欲しいですapt-get:)
Justme0

混同しないでくださいawk
jasonleonhard

35

grep 2.5.3は--exclude-dirパラメータを導入しました。これは思い通りに機能します。

grep -rI --exclude-dir=\.svn PATTERN .

環境変数を設定することもできます:GREP_OPTIONS = "-exclude-dir = .svn"

Andyのackへ投票は2番目です。それが一番です。


7
正確なバージョン番号について言及する場合は+1。grep 2.5.1を使用していて、exclude-dirオプションを使用できない
James

25

私は久々にこれを見つけました、次のように複数の包含と除外を追加できます:

grep "z-index" . --include=*.js --exclude=*js/lib/* --exclude=*.min.js

5
--exclude = {pattern1、pattern2、pattern3}
Yasser Sinjab

12

推奨されるコマンド:

grep -Ir --exclude="*\.svn*" "pattern" *

--excludeはベース名で機能するため、概念的には間違っています。つまり、現在のディレクトリにある.svnのみをスキップします。


3
うん、それは私にはまったく機能しません。私のために働いたのは:exclude-dir = .svn
Taryn East

2
@ニコラありがとうございます!なぜこれがうまくいかないのか私は髪を引き裂いてきました。教えてください、マンページからこれを発見する方法はありますか?それが言うすべてはそれが「パターン」に一致することです。 ここで説明するように、EDITのマンページには「ファイル」と記載されています。fixunix.com
unix /

11

grep 2.5.1では、この行を〜/ .bashrcまたは〜/ .bashプロファイルに追加する必要があります

export GREP_OPTIONS="--exclude=\*.svn\*"

9

私は時々grepのgrepの出力が非常に役立つと思います:

grep -rn "foo=" . | grep -v "Binary file"

ただし、それによってバイナリファイルの検索が実際に停止されるわけではありません。


10
grep -Iバイナリファイルをスキップするために使用できます。
Nathan Fellman、

私も若い頃にそれをしました...今私はよりよく知っていて、問題に直面したとき、最初のものは
RTFM

grepping grepは、色のハイライトを削除します。
Max Li

7

あなたがを使うことを嫌いでないならfind、私はその-prune機能が好きです:

find [directory] \
        -name "pattern_to_exclude" -prune \
     -o -name "another_pattern_to_exclude" -prune \
     -o -name "pattern_to_INCLUDE" -print0 \
| xargs -0 -I FILENAME grep -IR "pattern" FILENAME

最初の行で、検索するディレクトリを指定します。.(現在のディレクトリ)は、たとえば有効なパスです。

第2、第3ライン、使用には"*.png""*.gif""*.jpg"、など。これらの-o -name "..." -prune構成要素は、パターンの数だけ使用してください。

4行目では、必要なパターン-o( "or" toを指定)がもう1つfind必要であり、その最後にa -printまたはが必要-print0です。あなただけの剪定後に残ることを「他のすべて」したい場合は*.gif*.pngなどの画像は、その後、使用し -o -print0て、あなたは第四行で行われているが。

最後に、5行目は、作成されxargsた各ファイルを取得して変数に格納するパイプですFILENAME。その後、合格フラグをし、その後で展開されたファイル名のリストによって発見することになります。grep-IR"pattern"FILENAMExargsfind

特定の質問の場合、ステートメントは次のようになります。

find . \
     -name "*.png" -prune \
     -o -name "*.gif" -prune \
     -o -name "*.svn" -prune \
     -o -print0 | xargs -0 -I FILES grep -IR "foo=" FILES


私が提案する1つの修正:使用するのを忘れるか、ある種のコマンドが実際に除外したいファイルを印刷しないよう-falseに、それぞれの直後に含める:...-prune-print0exec-name "*.png" -prune -false -o name "*.gif -prune -false
OnlineCop

7

CentOS 6.6 / Grep 2.6.3では、次のように使用する必要があります。

grep "term" -Hnir --include \*.php --exclude-dir "*excluded_dir*"

(そうでない場合は「=」等号の欠如に注意してください--include--excludeinclude-dir--exclude-dir無視されます)


6

git grep

使用git grep性能や目的に合わせて最適化された特定のファイルを検索します。

デフォルトでは、バイナリファイルを無視し、を尊重します.gitignore。Git構造を使用していない場合でも、を渡すことで使用できます--no-index

構文例:

git grep --no-index "some_pattern"

その他の例については、以下を参照してください。


5

私は当然ですが、私の〜/ .bash_profileは次のようになります。

export GREP_OPTIONS = "-orl --exclude-dir = .svn --exclude-dir = .cache --color = auto" GREP_COLOR = '1; 32'

2つのディレクトリを除外するには、-exclude-dirを2回使用する必要があることに注意してください。


3

これを試してください:

$見つける。-name "* .txt" -type f -print | xargsファイル| grep "foo =" | カット-d:-f1

ここに設立:http : //www.unix.com/shell-programming-scripting/42573-search-files- exclude-binary-files.html


3
これはスペースを含むファイル名では機能しませんが、その問題は、printの代わりにprint0を使用してxargsに-0オプションを追加することで簡単に解決できます。
Adam Rosenfield、

3

非再帰的に検索する場合は、グロップパターンを使用してファイル名を照合できます。

grep "foo" *.{html,txt}

htmlとtxtが含まれます。現在のディレクトリのみを検索します。

サブディレクトリを検索するには:

   grep "foo" */*.{html,txt}

サブサブディレクトリ内:

   grep "foo" */*/*.{html,txt}

3

ディレクトリには、多くのバイナリファイルもあります。特定のディレクトリだけを検索することはできません(ディレクトリ構造は非常に混乱しています)。特定のファイルでのみgrepするより良い方法はありますか?

ripgrep

これは、現在のディレクトリを再帰的に検索するために設計された最も速いツールの1つです。これは、Rustで記述されており、Rustのregexエンジンの上に構築され、最大の効率を実現しています。詳細な分析はここで確認してください。

だからあなたはただ走ることができます:

rg "some_pattern"

それはあなた.gitignoreを尊重し、隠しファイル/ディレクトリとバイナリファイルを自動的にスキップします。

-g/ を使用して、ファイルやディレクトリを含めたり除外したりすることもできます--glob。グロッビングルールはグロブと一致し.gitignoreます。man rgヘルプを確認してください。

その他の例については、「grepで特定の拡張子に一致しないファイルを除外する方法」を参照してください

macOSでは、からインストールできますbrew install ripgrep


3

xargsはあなたの友達です。grepの--excludeではなく、それらを使用してファイルリストをフィルタリングします。

のようなものを試してください

find . -not -name '*.png' -o -type f -print | xargs grep -icl "foo="

これに慣れることの利点は、たとえばpng以外のすべてのファイルの行を数えるなど、他のユースケースに拡張できることです。

find . -not -name '*.png' -o -type f -print | xargs wc -l

PNG以外のすべてのファイルを削除するには:

find . -not -name '*.png' -o -type f -print | xargs rm

コメントで指摘されているように、一部のファイルの名前にスペースが含まれている可能性がある場合は-print0xargs -0代わりにおよびを使用してください。


1
これはスペースを含むファイル名では機能しませんが、その問題は、printの代わりにprint0を使用してxargsに-0オプションを追加することで簡単に解決できます。
Adam Rosenfield、

2

これらのスクリプトはすべての問題を解決するわけではありません...これをよりよく試してください:

du -ha | grep -i -o "\./.*" | grep -v "\.svn\|another_file\|another_folder" | xargs grep -i -n "$1"

このスクリプトは、「実際の」正規表現を使用してディレクトリが検索されないようにするため、非常に優れています。フォルダ名またはファイル名を「\ |」で区切るだけ grep -v

楽しめ!私のLinuxシェルで見つかりました!XD


2

@これ見てください。

grep --exclude="*\.svn*" -rn "foo=" * | grep -v Binary | grep -v tags

2
これをほぼ達成することは他の投稿でカバーされています。さらに、これは間違っています。さまざまなレイアウトオプションが設定されていると、行番号などが混乱したり、必要なコンテキストの行が除外されたりします。
Chris Morgan、

複数の「-v」オプションを同時に使用するにはどうすればよいですか?
道を開く

1

--binary-files=without-matchGNU のオプションでは、grepバイナリファイルをスキップします。(-I他の場所で説明されているスイッチと同等です。)

(これには、最新バージョンのが必要になる場合がありgrepます。少なくとも2.5.3にはそれが含まれています。)


1

tcsh .aliasファイルに適しています:

alias gisrc 'grep -I -r -i --exclude="*\.svn*" --include="*\."{mm,m,h,cc,c} \!* *'

{mm、m、h、cc、c}の部分が引用符で囲まれていてはいけないことを理解するのに少し時間がかかりました。〜キース


0

grepからのすべてのバイナリ結果を無視するには

grep -Ri "pattern" * | awk '{if($1 != "Binary") print $0}'

awkの部分はすべてのバイナリファイルfooの一致する行をフィルターで除外します


-2

これを試して:

  1. 「という名前のフォルダを作成します--F」currdir下..(またはにそこに名前を変更し、別のフォルダへのリンク「--F」すなわちdouble-minus-F
  2. #> grep -i --exclude-dir="\-\-F" "pattern" *
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.