UNIXシステムでfindコマンドによって返される結果の数を制限する方法はありますか?
一部のディレクトリに異常に多数のファイルがあるため、パフォーマンスの問題が発生しています。
私は次のようなことをしようとしています:
find /some/log -type f -name *.log -exec rm {} ; | limit 5000
xargs を探しているようですが、まだわかりません。
find /some/log/dir -type f -name "*.log" | xargs rm
find [...] |head -[NUMBER]
のようなものを試すことができます。これにより、SIGPIPE
が検索を続行しないようにfind
が多くの行を出力すると、head
がfind
に送信されます。
find /some/log -type f -name *.log -exec rm {} ; | limit 5000
もちろん、引用されているコマンドは機能しません(limit
は有効なコマンドでもありません)。
しかし、上記のfindコマンドに似たものを実行する場合、それはおそらく古典的な問題です。 find
がrm
ファイルごとに1回を実行するため、おそらくパフォーマンスの問題が発生しています。
xargs
を使用したい場合は、複数のファイルを1つのコマンドラインに組み合わせることができるため、一度に多くのファイルに対して限られた時間rm
を呼び出すことができ、これははるかに高速です。
ただ|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または終了するまでバックグラウンドで実行されるため、アイデアが歓迎されることです。
ディレクトリに非常に多くのファイルがある場合、および/またはパイプを使用する場合など、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" \;
したがって、この例は基本的に、パイプで課題に直面し、それでもより複雑なプログラミングオプションに進みたくない人のために投稿されています。