ファイルシステム全体でテキストを検索する方法は?


53

grepツールを使用する必要があると仮定すると、ファイルシステム全体でテキスト文字列「800x600」を検索したいと思います。

私は試した:

grep -r 800x600 /

しかし、それは機能しません。

私のコマンドがすべきだと思うことは、テキスト「800x600」のルートの下にあるすべてのファイル/フォルダーを再帰的にgrepし、検索結果を一覧表示することです。

何が間違っていますか?


2
「機能しない」とは、正確に何を意味するのでしょうか?出力を出力せず、ハングしたり、多くのPermission deniedエラーを出力しませんか?rootまたは通常のユーザーとして実行しましたか?
アレックス

私はいくつかの牽引力を得ています。まず、コマンドを実行しようとしてユーザーのホームディレクトリにいました。だから今、私はルートにcd /アウトしました。次に、上記と同じコマンドを試しましたが、多くのアクセス許可拒否エラーが発生しています。OK、だから今私はsudo grep -r 800x600 /を試してから/ proc / sysrq-triggerを取得します:入力/出力エラー
-Level1Coder

うーん、なぜ機能しないのかわかりません。を実行すると、アクセスエラーを無視できますgrep -r 800x600 / 2>/dev/null。ルートとして実行することもできます。
トーター14年

回答:


64

通常、このスタイルのコマンドを使用grepして、いくつかのファイルを実行します。

find / -xdev -type f -print0 | xargs -0 grep -H "800x600"

これが実際に行うことは、システム上のすべてのファイルのリストを作成し、各ファイルに対してgrep、指定された引数と各ファイルの名前で実行することです。

-xdev引数は、それが他のファイルシステムを無視しなければならないことがわかりを伝える-これは、次のような特殊なファイルシステムを回避するために良いです/proc。ただし、通常のファイルシステムも無視します。たとえば、/ homeフォルダーが別のパーティションにある場合、検索されません-と言う必要がありますfind / /home -xdev ...

-type fファイルのみを検索することを意味するため、ディレクトリ、デバイス、およびその他の特殊ファイルは無視されます(ディレクトリgrep内で再帰して内部のファイルで実行されます- grepディレクトリ自体では実行されませんが、とにかく動作しません)。そして、出力に常にファイル名を印刷する-Hようにgrep指示するオプション。

findファイルのリストをフィルタリングするためのあらゆる種類のオプションを受け入れます。たとえば-name '*.txt'、.txtで終わるファイルのみを処理します。-size -2M2メガバイトより小さいファイルを意味します。-mtime -5は、過去5日間に変更されたファイルを意味します。これらを-a for および and -o for またはで結合し、'('括弧')'を使用して式をグループ化します(引用符で囲んで、シェルがそれらを解釈しないようにします)。たとえば、次のとおりです。

find / -xdev '(' -type f -a -name '*.txt' -a -size -2M -a -mtime -5 ')' -print0 | xargs -0 grep -H "800x600"

見てみましょman find可能フィルタの完全なリストを参照してください。


2
特別なファイルシステムだけでなく、他のすべてのファイルシステム-xdevを除外することに注意してください。(たとえば、別のパーティションとしてマウントした場合、検索されません。)/home
cjm

私はそれぞれを実行しようとしましたが、両方ともエラーを返しましたfind: paths must precede expression: /
Level1Coder

1
注:正規表現が不要な場合、「fgrep」は「grep」よりも大幅に高速であるため、大きなツリーを検索する場合は大きな違いが生じます。
ネイサンキッド

1
を実行することで、xargs効率が向上する可能性がありfind / -xdev -type f -exec grep -H '800x600' +ます。
トーター14年

3
いいえ、コマンド+の最後の記号はfind実際には同じことを行います。複数の引数を持つxargs1つのgrepプロセスを生成します。
トーター14年

14

通常、システム上のすべてを実際に検索することは望ましくありません。Linuxはすべてにファイルノードを使用するため、一部の「ファイル」は検索したくないものです。たとえば/dev/sda、最初のハードドライブの物理ブロックデバイスです。おそらく、rawディスクデバイスではなく、マウントされたファイルシステムを検索する必要があります。また、/dev/randomそれを読むたびにランダムなデータを吐き出します。それを検索することはあまり意味がありません。/procファイルシステムは、あなたのケースでも問題があります。

私は2つのことのいずれかをお勧めします。

  1. ルートで検索するのではなく、役に立つと思われる場所のみを検索します。検索/homeまたは/usrまたは/etcseparatly。探している情報は特定のタイプである可能性が高いため、とにかく特定のフォルダーにある可能性があります。構成設定はにある必要があり/etcます。個人データファイルはにあるはず/homeです。検索をこのような主要な領域に限定すると、再帰的なgrepsに関する問題が大幅に軽減されます。

  2. 以下を使用--exclude-dirして、問題のある領域を除外します。
    grep -r --exclude-dir /proc --exclude-dir /dev --exclude-dir /tmp --exclude-dir /lost+found

最後に、大きな再帰grepを実行するときに、いくつかの「許可拒否」エラーが発生することは珍しくありません。通常の使用では、ユーザーが読み取れないファイルがあります。これらがごく少数の奇妙なファイルであり、ハードドライブのRAWデバイスやprocファイルシステム全体のようなものでない限り、エラーを無視してもかまいません。実際、すべてのエラーをnever never landに送信することで、コマンドラインでこれを行うことができます。

grep -r search_string /path 2> /dev/null

3
-Iバイナリ除外する
ラーフルパティル

2

簡単にするために、ack-grepをお勧めします。リンクack-grepは、より良いオプションである多くの場合を示しています。

使用するには、インストール後:

ack-grep pattern /

これを推奨してくれてありがとう、しかし、私はこれを実行しました、そして、それは本当に私が予想した検索結果を私に与えませんでした。欲しいものを得るには、多くの設定を微調整する必要があるようです。現在のところ、Richardの答えはそのまま使用できます。同様に有用であると思われるので、将来これを検討します。
Level1Coder


0

*その後、/ proc / sysrq-trigger:入出力エラーが発生します

実行中のプロセスで文字列をスキャンしようとしているため、コマンドは機能しています。このエラーが発生しています。

システムディレクトリを除外することをお勧めします

grep -exclude-dir = {proc、sys} "800x600" /


-3

単に正しい

grep -r "800x600" /

-現在のコマンドで間違っているのは、引用符 ""です。文字列引数は常にgrep引用符で囲みます。


3
これはここでは問題ではありません。この特定のタイプの引数をに与える場合、引用符は必要ありませんgrep。試してみてください。文字列「800x600」をファイルに挿入すると、grep 800x600 file正常に機能することがわかります。OPには明らかに他の問題があります。
slm
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.