ディレクトリ内のすべてのファイルで非再帰的にgrepを使用する方法は?


34

ディレクトリ内のすべてのファイルでテキストの文字列を検索したいです(サブディレクトリ-rではなく、オプションがそれを行うことは知っていますが、それは私が望んでいるものではありません)。

  1. ランニング

    grep "string" /path/to/dir
    

    これを行うことができるはずですが、私は読んでいますが、それは私にエラーを与えます:

    grep:dir:ディレクトリです

  2. 次に、grep複数のファイルで実行してみました。

    grep "string" .bashrc .bash_aliases 完全に動作します。

    grep "string" .bash* 意図したとおりに機能します。

    grep "string" * 私にエラーを与えます:

    grep: data: Is a directory
    grep: Desktop: Is a directory
    grep: Documents: Is a directory
    grep: Downloads: Is a directory
    ...
    

エラーのみが出力され、一致する行が表示されません。-sオプションを使用してみましたが、役に立ちませんでした。

だから、私の質問:

  1. grep(1)のように、できるはずなのにディレクトリで使用できないのはなぜですか?私はそれがインターネットでたくさんの例で行われているのを見てきました。
    編集:「ディレクトリでgrepを使用する」と言うとき、「そのサブディレクトリを除くそのディレクトリ内のすべてのファイルを検索する」という意味です。これは、ファイルの代わりにディレクトリを渡すときにgrepが行うことだと思います。私は間違っていますか?

  2. grep(2)のコマンドの動作を説明する仕組みについて説明してください。
    編集:より具体的にさせてください。なぜワイルドカードを使用して複数のファイルを指定して.bash**またはでなく、で検索するの./*ですか?

  3. を使用して、ディレクトリ内のすべてのファイル(およびサブディレクトリではない)を検索するにはどうすればよいgrepですか?


また*、グロブリングと呼ばれるのようなワイルドカードを展開するシェルに依存しています。グロビングには.bashrc、標準などのドットで始まるファイル名は含まれません。これらのファイルが含まれるようにシェルオプションを設定できますが、何をしているのかわからない場合は、少し混乱する可能性があります。グロビングを理解するための優れたガイドは、ここで見つける
Arronical

なぜだかわかりませんが、私はいつも隠しファイルのグロビングを行っており、常に機能しています。設定などは変更していません。(2)で指摘したように、それも機能しgrep "string" .bash*ます。
ジョンレッド

申し訳ありませんが、私の最後の例は間違っていました。Linuxは技術的にディレクトリを異なるタイプのファイルと見なしているため、隠しファイルも検索でき、「is a directory」を抑制できます。コマンドは次のようになります。 grep "string" * .* 2>/dev/nullまたはgrep -s "string" * .*
-Terrance

回答:


40

Bashでは、グロブは隠しファイルに展開されないため、ディレクトリ内のすべてのファイルを検索する場合は、隠しファイル.*と非隠しファイルを指定する必要があります*

「ディレクトリです」エラーを回避するには、を使用できます-d skipが、システムではエラーgrep: .gvfs: Permission deniedも表示されるため、-sすべてのエラーメッセージを非表示にするを使用することをお勧めします。

したがって、あなたが探しているコマンドは次のとおりです。

grep -s "string" * .*

別のディレクトリでファイルを検索する場合:

grep -s "string" /path/to/dir/{*,.*}

別のオプションは、dotglobシェルオプションを使用することです。これにより、グロブに隠しファイルが含まれるようになります。

shopt -s dotglob
grep -s "string" *

別のディレクトリ内のファイルの場合:

grep -s "string" /path/to/dir/*

†誰かがこのエラーを受け取ってはいけないと言った。彼らは正しいかもしれません-私はいくつかの読書をしましたが、自分でそれの頭や尾を作ることができませんでした。


間のスペースのために何らかの理由がある*とは.*
ハシム

2
@Hashimはの出力を比較echo * .*し、echo *.*自分のホームディレクトリで実行し、その差は明らかです。それ以外の場合はLMKと私はそれを説明します。
-wjandrea

おもしろいので、echo *隠されていないファイルとフォルダー、echo *.*隠されていないファイル、echo .*すべてのファイル、echo * .*すべてのファイルとディレクトリが表示されます。しかし、後者の場合に2つの間のスペースの理由はなぜですか?私には面倒です。2つを組み合わせて同じ結果を得る方法はありませんか?または、ここで2つを分離する必要がある理由の構文説明がありますか、それとも* .*例外的なケースですか?
ハシム

1
@Hashimどうやってそれらの結論に至ったのかわからないので、説明させてください。まず、ディレクトリはこのコンテキストのファイルです。グロブで*は、すべての隠されていないファイルを表します(つまり、ドットで始まらないファイル名)。.*(つまり、ファイル名のすべての隠されたファイルを表しますドットで始まる)を、そして、ドット*.*含むすべての隠されていないファイルを表します。ではecho * .*、彼らは異なるグロブているので、2つのグロブは別々でなければならない:1のために、隠されたための1つを非隠されました。答えで書いたよう*に、dotglobシェルオプションをオンにすることで、隠しファイルを含めることができます。
-wjandrea

1
*.*Windows(DOS)ではすべてのファイルをリストする方法として使用するのが一般的ですが、* nixではドットが含まれるファイルのみが含まれるため、* nixでは意味がありません。代わりに*、隠しファイルを除くすべてのファイルをリストし、隠しファイルをリストするために使用し.*ます。
トーマスラッター

10

-d skipオプションを追加する必要があります。

  1. Grepはファイル内を検索しています。前述のように、ディレクトリ内のファイルを検索する場合は、再帰的に検索できます。

  2. デフォルトでは、grepはすべてのファイルを読み取り、ディレクトリを検出します。デフォルトでは、-dオプションを使用してディレクトリをどう処理するかを定義していないため、エラーが出力されます。

  3. 親ディレクトリ内でのみ検索すると、 `grep -d skip" string "./*になります。


grepの詳細については、を参照してくださいman grep
anonymous2

(a)編集をご覧ください。(b)を使用-d skipしても機能しません。基本的にはと同じ-sです。また、編集を参照してください。(c)いいえ、grep -d skip "string" ./*機能しません。
ジョンレッド

7

古いタイマーはおそらくこれを行うでしょう:

find . -type f -print0 | xargs -0 grep "string"

3
どうしてfind . -type f -exec grep string {} +
-wchargin

5
あなたも欲しい-maxdepth 1
wchargin

@wchargin:あなたは、出力ファイル名をしたい場合、私はあなたがしたいと思うだけで、一つのファイルがありますfind . -type f -maxdepth 1 -exec grep string /dev/null {} +
グレゴリーニズビット

1
@GregoryNisbet:-Hgrepに渡すだけです。
17:23のwchargin

2

言い換える-1つのレベルのサブディレクトリでファイルをgrepしたいが、すべてのサブサブディレクトリを再帰しないか?

grep forthis  *  */*

または、現在のディレクトリにファイルが必要ない場合

grep forthis  */*

これは、ドットで始まるディレクトリを検出しないことに注意してください。

grep forthis  .*/*    */*   

その仕事をする必要があります。

また、コマンドで使用可能な制限パラメーターも-maxdepthあり-mindepthますfind


grep forthis */*現在のディレクトリと1つ下のディレクトリの両方のファイルを検索しませんか?
ハシム

@Hashim nopeほとんどの場合、cos */*は1つのスラッシュのみと一致します。a/b現在のディレクトリに名前のファイルがある場合、 `* / *はそれと一致します。
クリギー

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