複数のディレクトリのランダムソートと削除 (rm) を高速化します

複数のディレクトリのランダムソートと削除 (rm) を高速化します

基本的に BSD であるターミナルで MacOS を実行しているため、askdifferent ではなくここに質問を投稿します。後続の手順で、ファイルをランダムに削除して、画像データセットを縮小したいと考えています。一部のディレクトリには 100 万を超える jpg があります。私のデータは、maxdepth が 1 のサブディレクトリを持つマスター ディレクトリにあります。

-master
     -data1
       image.jpgs
     -data2
       image.jpgs
     -data3
       image.jpgs
     -data4
       image.jpgs
... and so forth

このリンクを見つけました:

https://superuser.com/questions/1186350/ディレクトリ内のランダムな1000個のファイルをすべて削除

...そしてこう思いつきました:

for f in *.jpg; do find "$f" -type f -print0 | sort -R | tail -n +50001 | xargs -0 rm; done

確かに動作しますが、サブディレクトリに対してこれを再帰的に実行して、すべてのディレクトリに対して手動で実行しなくて済むようにしたいと思います。質問/リクエストは次のとおりです。

  1. これを何らかの方法で最適化して速度を上げることはできますか?
  2. sort/tail は、50,000 個未満のファイルを含むディレクトリに遭遇するとエラーを返しますか?

答え1

リンクされたソース投稿を確認したところ、ループは実際には次のようになるようです。

for d in */; do find "$d" -iname '*.jpg' -type f -print0 | sort -zR | tail -zn +50001 | xargs -0r rm; done

ディレクトリから実行しますmaster

入力はヌルで区切られているため、と-zのオプションは必須です。 は 50000 行未満であれば文句を言いません。は気にせず、 は50000 行目以降は何もないので何も出力しません。 は引数なしで実行されると文句を言うかもしれませんが、GNU のオプションにより、入力がない場合には実行されなくなります(BSD xargs では不要ですが、文句を言うことはないでしょう)。sorttailsorttailrm-rxargsrm

最後に、最も重要なことですが、-zヌル区切りの入力オプションはおそらく BSD tail ではサポートされません。homebrew を使用してインストールできる GNU tail が必要になります。

ファイル名にスペース、改行、引用符、バックスラッシュなどが含まれていないことが保証されている場合は、おそらく null で区切られた行は不要です。その場合:

for d in */; do find "$d" -type f | sort -R | tail -n +50001 | xargs rm; done

関連情報