加速多个目录的随机排序和删除(rm)

加速多个目录的随机排序和删除(rm)

在本质上是 BSD 的终端中运行 MacOS,因此在这里发布我的问题而不是询问不同。我想通过随机删除文件来在后续步骤中修剪图像数据集。有些目录有超过 100 万张 jpg。我的数据位于主目录中,子目录的最大深度仅为 1:

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

我找到了这个链接:

https://superuser.com/questions/1186350/delete-all-but-1000-random-files-in-a-directory

...并想出了:

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

最后但最重要的是,-zBSD tail 可能不支持 null 分隔输入的选项。您需要 GNU tail,它可以使用自制程序安装。

如果你的文件名保证不包含空格、换行符、引号、反斜杠等,那么你可能不需要空分隔行。在这种情况下:

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

相关内容