web-dev-qa-db-ja.com

多くのファイルを含むディレクトリを処理するためにUnix検索結果の数を制限する方法

UNIXシステムでfindコマンドによって返される結果の数を制限する方法はありますか?

一部のディレクトリに異常に多数のファイルがあるため、パフォーマンスの問題が発生しています。

私は次のようなことをしようとしています:

find /some/log -type f -name *.log -exec rm {} ; | limit 5000
9
lemotdit

xargs を探しているようですが、まだわかりません。

find /some/log/dir -type f -name "*.log" | xargs rm
6
blahdiblah

find [...] |head -[NUMBER]のようなものを試すことができます。これにより、SIGPIPEが検索を続行しないようにfindが多くの行を出力すると、headfindに送信されます。

25
amphetamachine
find /some/log -type f -name *.log -exec rm {} ; | limit 5000

もちろん、引用されているコマンドは機能しません(limitは有効なコマンドでもありません)。

しかし、上記のfindコマンドに似たものを実行する場合、それはおそらく古典的な問題です。 findrmファイルごとに1回を実行するため、おそらくパフォーマンスの問題が発生しています。

xargsを使用したい場合は、複数のファイルを1つのコマンドラインに組み合わせることができるため、一度に多くのファイルに対して限られた時間rmを呼び出すことができ、これははるかに高速です。

0
sleske

ただ|head私にはうまくいきませんでした:

root@static2 [/home/dir]# find . -uid 501 -exec ls -l {} \; | head 2>/dev/null
total 620
-rw-r--r--  1 root   root           55 Sep  8 15:22 08E7384AE2.txt
drwxr-xr-x  3 lamav statlus 4096 Apr 22  2015 1701A_new_email
drwxr-xr-x  3 lamav statlus 4096 Apr 22  2015 1701B_new_email
drwxr-xr-x  3 lamav statlus 4096 May 11  2015 1701C_new_email
drwxr-xr-x  2 lamav statlus 4096 Sep 24 18:58 20150924_test
drwxr-xr-x  3 lamav statlus 4096 Jun  4  2013 23141_welcome_newsletter
drwxr-xr-x  3 lamav statlus 4096 Oct 31  2012 23861_welcome_email
drwxr-xr-x  3 lamav statlus 4096 Sep 19  2013 24176_welco
drwxr-xr-x  3 lamav statlus 4096 Jan 11  2013 24290_convel
find: `ls' terminated by signal 13
find: `ls' terminated by signal 13
find: `ls' terminated by signal 13
find: `ls' terminated by signal 13
find: `ls' terminated by signal 13

(...等...)

私の(間違いなく最善ではない)解決策:

find . -uid 501 -exec ls -l {} \; 2>/dev/null | head

欠点は、「検索」自体が必要な行数の後に終了せず、^ Cまたは終了するまでバックグラウンドで実行されるため、アイデアが歓迎されることです。

0
Putnik

ディレクトリに非常に多くのファイルがある場合、および/またはパイプを使用する場合など、xargsがシステムで許可される引数の数によって制限されるためなど、1つのオプションは終了を使用することです。次のアクションのフィルターとしてのexecコマンドのステータス。次のようになります。

rm /tmp/count ; find . -type f -exec bash -c 'echo "$(( $(cat /tmp/count) + 1 ))" > /tmp/count' \; -exec bash -c 'test $( cat /tmp/count ) -lt 5000' \; -exec echo "any command instead of echo of this file: {}" \;

最初のexecは、カウンターをインクリメントするだけです。 2番目のexecはカウントをテストし、5000未満の場合、0で終了し、次のコマンドが実行されます。 3番目のexecはファイルで意図されたとおりに実行されます。この場合は単純なエコーであり、-print-deleteなども実行できます(-deleteの代わりに-exec rm {} \;を使用します。インスタンス。

これはすべて、前のアクションが0を返すと仮定して、findアクションが順番に実行されるという事実に基づいています。

上記の例を使用するときは、/tmp/countが並行プロセスで使用されていないことを確認する必要があります。

[スコットからの次のコメントを編集]コメントをありがとうスコット。

それらに基づいて:最初のスレッドに一致するように、数は5,000に変更されました。

また、これは/ tmp/countファイルが42,000回(参照されているファイルの回数)書き込まれることは絶対に正しいので、「find」は42,000エントリすべてを通過しますが、対象のコマンド5,000のみを実行します。回数。したがって、このコマンドは全体の参照を回避することはなく、通常のパイプの代替オプションとして表示されます。この/ tmp/countファイルをホストするためにメモリマップされた一時ディレクトリを使用することは、適切であるように思われます。

そして、あなたのコメントに加えて、いくつかの追加の編集:パイプは、ほとんどの典型的なケースではより単純です。

ただし、パイプが簡単に適用されない理由については、以下をご覧ください。

  • ファイル名にスペースが含まれている場合、「find」execコマンドは、この場合をサポートするために、{}を引用符「{}」で囲むことを忘れたくないでしょう。

  • たとえば、目的のコマンドですべてのファイル名をrawに含めることができない場合は、次のようになります。-execsomespecificprogram -i "{}" -o "{}。myoutput" \;

したがって、この例は基本的に、パイプで課題に直面し、それでもより複雑なプログラミングオプションに進みたくない人のために投稿されています。

0
wang