#!/usr/bin/perl # Usage: perl enchunk.pl InputDirectory 700MB chunk* # use File::Copy; my $Dir = shift(); my $ChunkSize = shift(); my $OutputName = shift(); my $LenBaseDir = length($Dir) + 1; my %Units = ("KB"=>1024,"MB"=>1024**2,"GB"=>1024**3,"TB"=>1024**4); if($ChunkSize =~ /(\d+)(\w+)/){ $BaseNum = $1; $Unit = $2; if(!$Units{$Unit}){ die("Unknown unit \"$Unit\": Try using one of:" . join(",",keys(%Units)) . "\n"); } $ChunkSize = $BaseNum * $Units{$Unit}; } printf("Chunk size: %d bytes\n", $ChunkSize); $BytesDone = 0; $Chunk = 1; $Files = 0; GetOutputDir($Dir); %OkayDirs; ProcessDir($Dir,0); printf("Done, %d files, %d chunks\n", $Files, $Chunk); sub ProcessDir(){ my ($Dir,$Level) = @_; my $Indent = " " x $Level; print "Dir: $Indent$Dir\n"; opendir(my $dp, $Dir) || return; while($File = readdir($dp)){ $FullFile = "$Dir/$File"; if(-d $FullFile){ if($File ne "." && $File ne ".."){ ProcessDir($FullFile, $Level+1); } } elsif(-f $FullFile) { $BytesDone += -s $FullFile; if($BytesDone >= $ChunkSize){ $Chunk++; GetOutputDir(); $BytesDone = 0; } $Partial = substr($FullFile, $LenBaseDir); $Output = "$OutputDir/$Partial"; CheckCreateDir($Output); copy($FullFile, $Output) || die("$!\n"); $Files++; } } closedir($dp); } sub GetOutputDir(){ $OutputDir = $OutputName; $OutputDir =~ s/\*/$Chunk/g; } sub CheckCreateDir(){ my $Dir = shift(); return if($OkayDirs{$Dir}); @Parts = split(/[\/\\]/, $Dir); pop(@Parts); $Test = ""; foreach $Part(@Parts){ $Test .= "$Part/"; if(! -d $Test){ mkdir($Test); $OkayDirs{$Test} = 1; } } }