【发布时间】:2016-07-30 09:30:08
【问题描述】:
我有一个包含大约 250 万个文件的目录,超过 70 GB。
我想把它分成子目录,每个子目录有 1000 个文件。
这是我尝试使用的命令:
i=0; for f in *; do d=dir_$(printf %03d $((i/1000+1))); mkdir -p $d; mv "$f" $d; let i++; done
该命令在小范围内对我有用,但我可以让它在这个目录上运行几个小时,但它似乎什么也没做。
我愿意通过命令行以任何方式执行此操作:perl、python 等。无论以最快的方式完成此操作...
【问题讨论】:
-
您的
*需要一段时间才能扩展。也许从一个更有针对性的文件名子集开始,比如a*,看看它是否会在更合理的时间内返回。您可能还会考虑使用“查找”而不是 for 循环。另外我会担心在这个已经太大的目录中创建子目录。您是否考虑过在其他地方创建它们? -
我建议处理
find的结果。 -
只有写得很好的 shell 才能处理多 MB 大小范围内的命令或通配符扩展产生的字符串。在程序中读取目录既快速又容易(参见@ikegami)。 - 如果您想使用 shell 脚本:通过管道将
ls细分为while read ... done以逐个获取文件。 -
@laune: 让
*在for循环中扩展为 250 万个文件名不是问题本身 - 事实上,for f in *; do ...比ls | while read ...快很多。问题是对多个外部实用程序的 250 万次调用。 -
@mklement0 您不希望每个文件都有一个 mv。 1000 倍将其缩小到可管理的大小。 -- 但是最大命令长度为 2.088.198(根据 xargs --show-limits),我认为将 * 扩展为 250 万是行不通的。 ——所有这些只是表明这个任务对于 shell 脚本来说有点太多了。 Perl 已经足够好了,我们都知道它对 C(甚至 Java)来说是小菜一碟。
标签: python bash perl shell command-line