Bizarrely your code should do what you wanted.
A file glob like <*.JPG>
in scalar context will return the next file that matches the pattern, and since both while
and rename
apply scalar context, the two globs return the same value at each iteration.
while (<*.JPG>) {
s/JPG$/jpg/;
rename <*.jpg>, $_;
}
In the first iteration of the loop $_
is set to IMG_0178.JPG
by the while
, and the substitution sets the file type to lower case.
Then in the rename <*.jpg>
is executed in scalar context and again returns IMG_0178.JPG
- the first file in the same list because Windows file names are case-insensitive.
So finally the rename performs rename 'IMG_0178.JPG', 'IMG_0178.jpg'
as required.
Rewriting rename
like this shows this clearly
sub ren($$) {
print "$_[0] -> $_[1]\n";
}
while (my $file = <*.JPG>) {
$file =~ s/JPG$/jpg/;
ren <*.JPG>, $file;
}
output
IMG_0178.JPG -> IMG_0178.jpg
IMG_0182.JPG -> IMG_0182.jpg
IMG_0183.JPG -> IMG_0183.jpg
IMG_0184.JPG -> IMG_0184.jpg
IMG_0186.JPG -> IMG_0186.jpg
So you are lucky, and your files should have been renamed as you wanted.
But don't do this. In particular you should run the program with a print statement in place of any critical operations so that you can see what is going to happen.
This would be better as id more clearly does what is intended
perl -e '($f = $_) =~ s/JPG$/jpg/i and rename $_, $f while <*.JPG>'