基本的に 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
確かに動作しますが、サブディレクトリに対してこれを再帰的に実行して、すべてのディレクトリに対して手動で実行しなくて済むようにしたいと思います。質問/リクエストは次のとおりです。
- これを何らかの方法で最適化して速度を上げることはできますか?
- 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 では不要ですが、文句を言うことはないでしょう)。sort
tail
sort
tail
rm
-r
xargs
rm
最後に、最も重要なことですが、-z
ヌル区切りの入力オプションはおそらく BSD tail ではサポートされません。homebrew を使用してインストールできる GNU tail が必要になります。
ファイル名にスペース、改行、引用符、バックスラッシュなどが含まれていないことが保証されている場合は、おそらく null で区切られた行は不要です。その場合:
for d in */; do find "$d" -type f | sort -R | tail -n +50001 | xargs rm; done