回答:
xargsを探しているようですが、まだ知らないようです。
find /some/log/dir -type f -name "*.log" | xargs rm
-exec rm {} +
オーバーヘッドなしで同じことをします。あなたが追加できるもののhead
パイプチェーンに:find [...] | head -5000 | xargs rm
find ...|xargs
である危険ないくつかのファイル名が変な文字が含まれている場合、それはおかしい/奇妙/悲惨な事をするだろうとして、。常に使用しますfind ... -print0 | xargs -0
(GNU拡張機能、私は信じています)。
-exec rm...
またはxargs rm
findの-delete
フラグを使用できます。
のようなものを試すことができfind [...] |head -[NUMBER]
ます。これは、その多くの行を出力SIGPIPE
するfind
ときにto を送信するため、検索を続行head
しfind
ません。
find
望んでいるのはサンプルだけであるときに(潜在的に巨大な)ファイルシステムを走査し続けると想定していました(私の特定のユースケースは、すべてのディレクトリから1つのファイルを取得することです)。
find /some/log -type f -name *.log -exec rm {} ; | limit 5000
さて、引用されたコマンドはもちろん動作しlimit
ません(有効なコマンドではありません)。
ただし、上記のfindコマンドに類似した何かを実行する場合、おそらく古典的な問題です。すべてのファイルに対して1回find
実行さrm
れるため、おそらくパフォーマンスの問題が発生しています。
を使用する場合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
欠点は、「find」自体が必要な行数で終了せず、^ Cまたは終了までバックグラウンドで実行されるため、アイデアが歓迎されることです。
ディレクトリに非常に多くのファイルがある場合、および/またはxargsがシステムで許可されている引数の数によって制限されるためにパイプを使用する場合などが適用されない場合、1つのオプションはexitを使用することです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 {} \;
します)。
これはすべてfind
、前のアクションが0を返すと仮定してアクションが順番に実行されるという事実に基づいています。
上記の例を使用する場合/tmp/count
、同時プロセスで使用されていないことを確認する必要があります。
[スコットからのコメントに続く編集]スコット、コメントありがとう。
それらに基づいて:最初のスレッドに合わせて番号が5,000に変更されました。
また、これは/ tmp / countファイルが42,000回(閲覧されるファイルと同じ回数)書き込まれるため、「find」はすべての42,000エントリを通過しますが、対象のコマンドは5,000回。したがって、このコマンドは全体の閲覧を回避せず、通常のパイプの代替オプションとして表示されます。メモリマップされた一時ディレクトリを使用して、この/ tmp / countファイルをホストするのが適切と思われます。
そして、あなたのコメントに加えて、いくつかの追加の編集:ほとんどの典型的な場合、パイプはよりシンプルになります。
ただし、パイプが簡単に適用されない理由は以下のとおりです。
ファイル名にスペースが含まれる場合、「find」execコマンドは、このケースをサポートするために、引用符「{}」で{}を囲むことを忘れたくないでしょう。
目的のコマンドがすべてのファイル名を未加工のままにできない場合、たとえば次のようになります。-exec somespecificprogram -i "{}" -o "{} .myoutput" \;
そのため、この例は基本的に、パイプに関する課題に直面し、さらに精巧なプログラミングオプションを使用したくない人のために投稿されています。
.log
削除したい42 000個のファイルがありますが、一度に削除できるのは5 000個だけだと思います。 このソリューションは、最初のN個の ファイルのみでアクション(削除など)を実行します(紛らわしいこと に、OPの5 000ではなくN = 10で答えを書いています)が、count
ファイルを42 000回更新します。
\;
単なるものではないと仮定すべき;
ですか?