在Unix上将非常大的目录拆分成较小的目录的单行程序

Lan*_*ard 5 unix filesystems shell wget

在UNIX上,如何将包含可能数百万个文件的非常大的目录拆分为某些自定义最大文件数的较小目录,例如每个目录100个?

如果您知道wget将文件自动下载到这些子目录的方法,则可获得奖励积分.因此,如果.html在顶级路径上有100万页www.example.com,例如

/1.html
/2.html
...
/1000000.html
Run Code Online (Sandbox Code Playgroud)

我们每个目录只需要100个文件,它会将它们下载到类似的文件夹中

./www.example.com/1-100/1.html
...
./www.example.com/999901-1000000/1000000.html
Run Code Online (Sandbox Code Playgroud)

只有在wget下载文件后才真正需要能够在文件夹上运行UNIX命令,但如果可以在wget下载时执行此操作,我很乐意知道!

Bar*_*den 3

您可以通过几个循环运行它,这应该可以解决问题(至少对于文件名的数字部分)。我认为把这当作一句俏皮话来做这件事过于乐观了。

#! /bin/bash
for hundreds in {0..99}
do
    min=$(($hundreds*100+1))
    max=$(($hundreds*100+100))
    current_dir="$min-$max"
    mkdir $current_dir
    for ones_tens in {1..100}
    do
        current_file="$(($hundreds*100+$ones_tens)).html"
        #touch $current_file 
        mv $current_file $current_dir
    done
done
Run Code Online (Sandbox Code Playgroud)

我通过首先注释掉mkdir $current_dirmv $current_file $current_dir取消注释来进行性能测试touch $current_file。这将创建 10000 个文件(1000000 个文件目标的百分之一)。创建文件后,我恢复了所写的脚本:

$ time bash /tmp/test.bash 2>&1 

real        0m27.700s
user        0m26.426s
sys         0m17.653s
Run Code Online (Sandbox Code Playgroud)

只要您不跨文件系统移动文件,每个mv命令的时间就应该是恒定的,因此您应该会看到相似或更好的性能。如果将其扩展到 100 万个文件,则需要大约 27700 秒,即 46 分钟。有多种优化途径,例如在一个命令中移动给定目录的所有文件,或删除内部 for 循环。

执行“wget”来获取一百万个文件将花费比这更长的时间,并且几乎肯定需要一些优化;仅在 http 标头中保留带宽就可以将运行时间减少几个小时。我认为 shell 脚本可能不是适合这项工作的工具;在 cpan 上使用诸如 WWW::Curl 之类的库将更容易优化。