両方のコマンドを試しましたが、コマンドfind | grep "filename"
は単純なコマンド。
この動作の適切な説明は何ですか?
コメント
- あなたすべてのファイルをfindでリストし、データをgrepに渡して処理します。 'でfindを使用すると、リストされているすべてのファイルをgrepに渡して出力を解析する手順がありません。したがって、これはより速くなります。
- どのような意味で遅くなりますか?コマンドの完了にかかる時間は異なりますか?
- これをローカルで再現することはできません'。どちらかといえば、
time find "$HOME" -name '.profile'
はtime find "$HOME" | grep -F '.profile'
よりも長い時間を報告します。 (17秒対12秒)。 - @JenniferAnderson両方を繰り返し実行しました。 17秒と12秒は平均です。はい、
grep
のバリエーションはfind
の結果のどこにでも一致しますが、find -name
は完全に一致するだけです(この場合)。 - はい、
find filename
高速です。これはタイプミスであり、OPはfind -name filename
を意味していると思いました。find filename
では、filename
のみが検査されます(他には何も検査されません)。
回答
(ここではGNU find
を想定しています)
使用するだけです
find filename
は、filename
または
ディレクトリの場合、またはその名前が現在のディレクトリに存在しない場合はエラー。これは、ls filename
と同様の非常に迅速な操作です(ただし、filename
がディレクトリの場合は再帰的です)。
In対照的に、
find | grep filename
は、find
がすべての名前のリストを生成できるようにします。 grep
がフィルタリングする現在のディレクトリ以下。これは明らかに、はるかに遅い操作になります。
実際にはだったと思います。 意図したもの
find . -type f -name "filename"
これにより、filename
が通常のファイルの名前として検索されます。現在のディレクトリ以下。
これはfind | grep filename
と同じくらい速く(または比較的速く)なりますが、grep
ソリューションは、-path "*filename*"
がivid = “778e7df849″で行うのと同様に、見つかった各名前のフルパスに対してfilename
を照合します。 >
。
混乱は、は機能します。
ユーティリティはいくつかのパスを取り、これらのパスの下にあるすべての名前を返します。
その後 >ファイル名、パス、タイムスタンプ、ファイルサイズ、ファイルタイプなどに作用する可能性のあるさまざまなテストを使用して、返される名前を制限します。
言うとき
find a b c
find
に、3つのパスa
で使用可能なすべての名前をリストするように依頼します。 b
およびc
。これらがたまたま現在のディレクトリ内の通常のファイルの名前である場合、これらは返されます。それらのいずれかがディレクトリの名前である場合は、そのディレクトリ内のそれ以降のすべての名前とともに返されます。
実行する場合
find . -type f -name "filename"
これにより、現在のディレクトリ(.
)以下のすべての名前のリストが生成されます。次に、名前を通常のファイルの名前に制限します。つまり、ディレクトリなどではなく、-type f
を使用します。次に、-name "filename"
を使用してfilename
に一致する名前にさらに制限があります。文字列filename
は、*.txt
などのファイル名グロブパターンである可能性があります(引用することを忘れないでください)。
例:
以下は、私のホームディレクトリで.profile
というファイルを「検索」しているようです。
$ pwd /home/kk $ find .profile .profile
ただし、実際には、パス.profile
にあるすべての名前を返すだけです(名前は1つだけで、このファイルのものです)。
次に、cd
1レベル上に移動して、再試行します:
$ cd .. $ pwd /home $ find .profile find: .profile: No such file or directory
find
コマンドは.profile
というパスを見つけることができなくなりました。
ただし、現在のディレクトリを確認し、返された名前を.profile
のみに制限すると、そこからも:
$ pwd /home $ find . -name ".profile" ./kk/.profile
コメント
回答
非技術的な説明:群衆の中でジャックを探しています群衆の中のすべての人を探して、ジャック以外のすべてを考慮から除外するよりも高速です。
コメント
- 問題は、OPがジャックに期待していることです。群衆の中で唯一の人になります。もしそうなら、彼らは'幸運です。
find jack
は、jack
というファイルが'の場合、jack
を一覧表示します。 >
、またはディレクトリ内のすべての名前(' saディレクトリの場合)。 ' find
の仕組みについての誤解です。
回答
まだ問題を理解していませんが、さらに洞察を提供できます。
クサラナンダのようにfind | grep
私のシステムでは明らかに高速ですが、あまり意味がありません。最初は、ある種のバッファリングの問題を想定していました。コンソールに書き込むと、次のファイル名を読み取るための次のシステムコールまでの時間が遅くなります。パイプへの書き込みは非常に高速です。32バイトの書き込みでも約40MiB /秒です(私のかなり遅いシステムでは、1MiBのブロックサイズで300MiB /秒)。したがって、find
は、パイプ(またはファイル)への書き込み時にファイルシステムからの読み取りを高速化できるため、ファイルパスの読み取りとコンソールへの書き込みの2つの操作を並行して実行できると想定しました(これは、シングルスレッドプロセスとしてのfind
だけでは実行できません。
それはfind
の障害
2つの呼び出しの比較
:> time find "$HOME"/ -name "*.txt" >/dev/null real 0m0.965s user 0m0.532s sys 0m0.423s
および
:> time find "$HOME"/ >/dev/null real 0m0.653s user 0m0.242s sys 0m0.405s
は、find
が信じられないほど愚かなことをしていることを示しています(それが何であれ)。 -name "*.txt"
の実行にはまったく能力がないことが判明しました。
入力/出力比に依存する可能性があります
書くものがほとんどない場合は、find -name
が勝つと思うかもしれませんが、find -name
はもっと恥ずかしいだけです。 div id = “778e7df849″>
。何も書かなくても失われますgrep
の200Kファイル(13Mのパイプデータ)に対して:
time find /usr -name lwevhewoivhol
find
はgrep
と同じくらい高速ですが、
find
のname
に対する愚かさは他のテストには及ばないことがわかりました。代わりに正規表現を使用すると、問題は解消されます。
:> time find "$HOME"/ -regex "\.txt$" >/dev/null real 0m0.679s user 0m0.264s sys 0m0.410s
これはバグと見なすことができると思います。バグレポートを提出してくれる人はいますか?私のバージョンはfind(GNU findutils)4.6.0
コメント
- タイミングはどの程度再現可能ですか?最初に
-name
テストを実行した場合は、ディレクトリの内容がキャッシュされていないため、速度が低下している可能性があります。 (-name
と-regex
をテストすると、少なくともキャッシュ効果が考慮された後は、ほぼ同じ時間がかかることがわかります。もちろん、find
…) - @psmearsの異なるバージョンである可能性があります。もちろん、私はこれらのテストを数回実行しました。キャッシングの問題は、最初の回答の前の質問へのコメントでも言及されています。私の
find
バージョンはfind(GNU findutils)4.6.0 -
-name '*.txt'
の追加が遅くなるのはなぜ驚くべきことですかfind
?各ファイル名をテストして、追加の作業を行う必要があります。 - @Barmar一方で、この追加の作業は非常に高速に実行できます。一方、この余分な作業は他の作業を節約します。
find
はより少ないデータを書き込む必要があります。また、パイプへの書き込みは非常に遅い操作です。 - ディスクへの書き込みは非常に遅く、パイプへの書き込みはそれほど悪くはなく、カーネルバッファにコピーするだけです。最初のテストでは、
/dev/null
にさらに書き込むと少ないシステム時間が使用されたことに注意してください。
回答
通知:私はあなたが<を意味すると仮定しますdiv id = "189f5af014">
(それ以外の場合は、別のものを探しています。find filename
は、実際には filename というパスを調べます。ファイルがほとんど含まれていない可能性があるため、すぐに終了します)。
5000個のファイルを保持するディレクトリがあるとします。ほとんどのファイルシステムでは、これらのファイルは実際には tree 構造に保存されているため、特定のファイルをすばやく見つけることができます。
したがって、find
に、名前を確認するだけでよいファイルを見つけるように依頼すると、find
が質問します。 > そのファイルの場合、およびそのファイルのみを、大容量記憶装置からごくわずかなページを読み取る基になるファイルシステムに送信します。したがって、ファイルシステムがその価値がある場合、この操作はツリー全体をトラバースしてすべてのエントリを取得するよりもはるかに高速に実行されます。
プレーンなfind
を要求するときは、それがまさにあなたが行うことですが、ツリー全体をトラバースして、読み取ります。すべて。単一。エントリ。大きなディレクトリでは、これは問題になる可能性があります(ディスクに大量のファイルを保存する必要があるいくつかのソフトウェアが、2つまたは3つのコンポーネントの深さで「ディレクトリツリー」を作成する理由です。このように、すべてのリーフが保持する必要があるファイルは少なくなります) 。
回答
ファイル/ john / paul / george / ringo / beatlesが存在し、検索しているファイルを想定します。は「ストーン」と呼ばれます
find / stones
findは「ビートル」を「ストーン」と比較し、「s」と「b」が一致しない場合はドロップします。
find / | grep stones
この場合、findは「/ john / paul / george / ringo / beatles」をgrepとgrepwilに渡します。一致するかどうかを判断する前に、パス全体を処理する必要があります。
grepははるかに多くの作業を行っているため、時間がかかります
コメント
- 試してみましたか?
- 文字列比較のコスト(非常に単純で安価)は、IO(またはキャッシュされている場合はsyscall)のコストによって完全に小さくなります。ディレクトリルックアップの。
- grep isn ' ta文字列比較、つまり正規表現の比較。つまり、いずれかが見つかるまで文字列全体を処理する必要があります。試合または最後に到達します。ディレクトリルックアップは何があっても同じです。
- @Paranoidうーん、どのバージョンの find について話しているのですか? 'は、Debianで慣れている find I 'のようなものではないようです。
find filename
は、filename
のタイプが directory でない場合(またはタイプdirectoryの場合、filename
のみを返します。ただし、エントリ自体はありませんでした)