N
Niall Macpherson
I have a hash which uses a filename as a key. The filenames should all
have an extension which consists of three digits. I need a function
will return the name of the next filename in the sequence - e.g if I
have /a/b/c/xx.001, /a/b/c/xx.002, /a/b/c/xx.003 as my hash keys I
need to return /a/b/c/xx.004. It is permitted for the sequence to have
gaps, eg we could have /a/b/c/xx.001, /a/b/c/xx.006, /a/b/c/xx.012 and
the next filename generated would be /a/b/c/xx.013
The following code seems to do what I want but it does seem very long
winded. Am I missing a far neater way of doing this ? Thanks
use strict;
use warnings;
##------------------------------------------------------------------
sub GetNextFileName
{
## There must be a more elegant way of doing this !
my($rh_chunkinfo) = @_;
my $biggest = -1;
my($filebase, $number) = ("", -1);
foreach my $fname ( keys %$rh_chunkinfo )
{
($filebase, $number) = split (/\./, $fname);
if($number !~ /\d\d\d/)
{
return('Error');
}
my $fno = -1;
## get the filenumber
if($number =~ /^0*$/)
{
## all zeroes
$fno = 0;
}
else
{
## strip leading zeroes
$number =~ s/^0*//;
$fno = $number;
}
if($fno > $biggest)
{
$biggest = $fno;
}
}
## Assume 3 digits, left padded with 0's
my $zeroes = '0' x (3 - length($biggest + 1));
my $nextfilename = sprintf("%s.%s%d", $filebase, $zeroes, $biggest +
1);
return($nextfilename);
}
##------------------------------------------------------------------
my %chunkinfo;
my($id, $fname, $size, $used, $nchunks) = (-1, "", -1, -1, -1);
while (<DATA>)
{
chomp;
($id, $fname, $size, $used, $nchunks) = split(/\|/);
$chunkinfo{$fname}{id} = $id;
$chunkinfo{$fname}{fname} = $fname;
$chunkinfo{$fname}{size} = $size;
$chunkinfo{$fname}{used} = $used;
$chunkinfo{$fname}{nchunks} = $nchunks;
}
my $nextfilename = GetNextFileName(\%chunkinfo);
print 'Next filename is ' . $nextfilename . "\n";
exit(0);
__END__
1|C:/somepath/file.001|1000|100|3
2|C:/somepath/file.006|2000|300|5
3|C:/somepath/file.003|2000|600|5
4|C:/somepath/file.004|1000|100|2
5|C:/somepath/file.002|500|200|6
6|C:/somepath/file.005|750|150|8
have an extension which consists of three digits. I need a function
will return the name of the next filename in the sequence - e.g if I
have /a/b/c/xx.001, /a/b/c/xx.002, /a/b/c/xx.003 as my hash keys I
need to return /a/b/c/xx.004. It is permitted for the sequence to have
gaps, eg we could have /a/b/c/xx.001, /a/b/c/xx.006, /a/b/c/xx.012 and
the next filename generated would be /a/b/c/xx.013
The following code seems to do what I want but it does seem very long
winded. Am I missing a far neater way of doing this ? Thanks
use strict;
use warnings;
##------------------------------------------------------------------
sub GetNextFileName
{
## There must be a more elegant way of doing this !
my($rh_chunkinfo) = @_;
my $biggest = -1;
my($filebase, $number) = ("", -1);
foreach my $fname ( keys %$rh_chunkinfo )
{
($filebase, $number) = split (/\./, $fname);
if($number !~ /\d\d\d/)
{
return('Error');
}
my $fno = -1;
## get the filenumber
if($number =~ /^0*$/)
{
## all zeroes
$fno = 0;
}
else
{
## strip leading zeroes
$number =~ s/^0*//;
$fno = $number;
}
if($fno > $biggest)
{
$biggest = $fno;
}
}
## Assume 3 digits, left padded with 0's
my $zeroes = '0' x (3 - length($biggest + 1));
my $nextfilename = sprintf("%s.%s%d", $filebase, $zeroes, $biggest +
1);
return($nextfilename);
}
##------------------------------------------------------------------
my %chunkinfo;
my($id, $fname, $size, $used, $nchunks) = (-1, "", -1, -1, -1);
while (<DATA>)
{
chomp;
($id, $fname, $size, $used, $nchunks) = split(/\|/);
$chunkinfo{$fname}{id} = $id;
$chunkinfo{$fname}{fname} = $fname;
$chunkinfo{$fname}{size} = $size;
$chunkinfo{$fname}{used} = $used;
$chunkinfo{$fname}{nchunks} = $nchunks;
}
my $nextfilename = GetNextFileName(\%chunkinfo);
print 'Next filename is ' . $nextfilename . "\n";
exit(0);
__END__
1|C:/somepath/file.001|1000|100|3
2|C:/somepath/file.006|2000|300|5
3|C:/somepath/file.003|2000|600|5
4|C:/somepath/file.004|1000|100|2
5|C:/somepath/file.002|500|200|6
6|C:/somepath/file.005|750|150|8