Skip to main content
 首页 » 编程设计

language-agnostic之将大目录拆分为子目录

2025年05月04日26pander-it

我有一个包含大约 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 等。只要是最快完成此操作的任何方式...

请您参考如下方法:

我怀疑如果您检查过,您会注意到您的程序实际上正在移动文件,尽管速度非常慢。启动一个程序相当昂贵(至少与进行系统调用相比),而且每个文件要启动三到四次!因此,以下应该更快:

perl -e' 
   my $base_dir_qfn = "."; 
   my $i = 0; 
   my $dir; 
   opendir(my $dh, $base_dir_qfn) 
      or die("Can'\''t open dir \"$base_dir_qfn\": $!\n"); 
 
   while (defined( my $fn = readdir($dh) )) { 
      next if $fn =~ /^(?:\.\.?|dir_\d+)\z/; 
 
      my $qfn = "$base_dir_qfn/$fn"; 
 
      if ($i % 1000 == 0) { 
         $dir_qfn = sprintf("%s/dir_%03d", $base_dir_qfn, int($i/1000)+1); 
         mkdir($dir_qfn) 
            or die("Can'\''t make directory \"$dir_qfn\": $!\n"); 
      } 
 
      rename($qfn, "$dir_qfn/$fn") 
         or do { 
            warn("Can'\''t move \"$qfn\" into \"$dir_qfn\": $!\n"); 
            next; 
         }; 
 
      ++$i; 
   } 
'