Unix FIND結果数を制限する方法


7

UNIXシステムでFINDコマンドによって返される結果の数を制限する方法はありますか?一部のディレクトリのファイル数が異常に多いため、パフォーマンスの問題が発生しています。

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

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

3
私たちはそれが\;単なるものではないと仮定すべき;ですか?
プートニク

回答:


4

xargsを探しているようですが、まだ知らないようです。

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

3
-exec rm {} +オーバーヘッドなしで同じことをします。あなたが追加できるもののheadパイプチェーンに:find [...] | head -5000 | xargs rm
いんちきキホーテ

6
ちょうどノートfind ...|xargsである危険ないくつかのファイル名が変な文字が含まれている場合、それはおかしい/奇妙/悲惨な事をするだろうとして、。常に使用しますfind ... -print0 | xargs -0(GNU拡張機能、私は信じています)。
sleske

10
代わりに、-exec rm...またはxargs rmfindの-deleteフラグを使用できます。
マーティンヒルトン

20

のようなものを試すことができfind [...] |head -[NUMBER]ます。これは、その多くの行を出力SIGPIPEするfindときにto を送信するため、検索を続行headfindません。


-exec argも使用していることを付け加える必要がありました。コマンドがLSのようなものである場合、HEADは機能します。しかし、私はRMを使用しており、それは1回の実行ですべてのファイルを取得するようですので、私の場合は機能しません。find / some / log -type f -name * .log -exec rm {}; | ヘッド-5000
lemotdit

6
-exec rmを使用する代わりに、findの結果を提案どおりにheadにパイプしてから、結果をxargsとrmにパイプします。
ポールR

知っておくといい。私がfind望んでいるのはサンプルだけであるときに(潜在的に巨大な)ファイルシステムを走査し続けると想定していました(私の特定のユースケースは、すべてのディレクトリから1つのファイルを取得することです)。
スリダールサルノバト

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

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

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

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


「limit」は有効なコマンドではありません。正しくエスケープされていません。これは機能しません。
amphetamachine

@amphetamachine:質問を引用しただけです。もちろん、あなたは正しいです。
sleske

0

|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または終了までバックグラウンドで実行されるため、アイデアが歓迎されることです。


0

ディレクトリに非常に多くのファイルがある場合、および/または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" \;

そのため、この例は基本的に、パイプに関する課題に直面し、さらに精巧なプログラミングオプションを使用したくない人のために投稿されています。


私は質問を完全に理解していません-OPには.log削除したい42 000個のファイルがありますが、一度に削除できるのは5 000個だけだと思います。  このソリューションは、最初のN個の  ファイルのみでアクション(削除など)を実行します(紛らわしいこと に、OPの5 000ではなくN = 10で答えを書いています)が、countファイルを42 000回更新します。
スコット

1
まず第一に、スーパーユーザーへようこそ!私たちは常に新しいコミュニティメンバーからの貢献に感謝していますが、明らかに2つのスーパーユーザーアカウントがあります。これこのアカウントです。次のヘルプセンターチュートリアルを利用して、スーパーユーザースタッフにアカウントの統合を依頼してください。誤って2つのアカウントを作成しました。どうすればそれらをマージできますか?
Run5k
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.