Requirement 1:
Find filenames within a directory that look like '\A\d+\.jpg\z'. (I prefer \A and \z over ^ and $ as \A and \z match 'beginning of string' and 'end of string' as opposed to 'beginning of line' and 'end of line')
my(@filenames, $directory);
opendir($directory, $directory_path)
or die "opendir of $directory_path failed: $!\n";
@filenames = grep /\A\d+\.jpg\z/, readdir($directory);
closedir($directory);
Requirement 2:
Extend filenames such that they follow the form '\A\d{6,}\z'.
$filename = sprintf("%06d.jpg", $1) if $filename =~ /\A(\d+)\.jpg\z/;
Requirement 3:
Creating directory (if it does not already exist) and moving files into the directory.
use File::Spec;
-d $subdir_path
or mkdir($subdir_path, 0777)
or die "mkdir of $subdir_path failed: $!\n";
rename($filename, File::Spec->catfile($subdir_path, $filename))
or die "rename of $filename failed: $!\n";
Requirement 4:
Matching the first three (or more?) digits in the string.
$filename =~ /\A(\d*)\d{3}\.jpg\z/; # result stored in $1
Final Solution:
Putting this all together, we get:
use File::Spec;
for my $directory_path (@ARGV) {
my $directory;
my @filenames;
# Determine @filenames to work with in $directory_path.
opendir($directory, $directory_path)
or die "opendir of $directory_path failed: $!\n";
@filenames = grep /\A\d+\.jpg\z/, readdir($directory);
closedir($directory);
for (@filenames) {
my($basename, $prefix) = /\A((.+).{3})\.jpg\z/s or next;
my $subdir_path = File::Spec->catdir($directory_path, $prefix)
+;
# Create the subdir if it does not yet exist.
-d $subdir_path
or mkdir($subdir_path, 0777)
or die "mkdir of $subdir_path failed: $!\n";
my $old_path = File::Spec->catfile($directory_path, $_);
my $new_path = File::Spec->catfile($subdir_path, sprintf("%06d
+.jpg", $basename));
# Move the file to the subdir.
rename($old_path, $new_path)
or die "rename of $old_path to $new_path failed: $!\n";
}
}
Edit to by tye to remove PRE tags around CODE tags
|