Debugging Single Line Perl to Rename Files

I tested / tested this one line Perl and I am trying to figure out what happened to the files. I no longer see the files. Did I delete them or what went wrong?

Example of the listed file names (original):

IMG_0178.JPG IMG_0182.JPG IMG_0183.JPG IMG_0184.JPG IMG_0186.JPG 

I just wanted to change the file extension to lowercase (.jpg):

 perl -e'while(<*.JPG>) { s/JPG$/jpg/; rename <*.jpg>, $_ }' 
+4
source share
2 answers

Do not use rename with glob. Use scalars. Try to assign the file name to a new variable before replacing and rename the old name to the changed one, for example:

 perl -e'while(<*.JPG>) { ($new = $_) =~ s/JPG$/jpg/; rename $_, $new }' 

Check the output with ls -1 :

 IMG_0178.jpg IMG_0182.jpg IMG_0183.jpg IMG_0184.jpg IMG_0186.jpg 
+9
source

Unusually, your code should do what you wanted.

A glob file, such as <*.JPG> in a scalar context, will return the next file matching the pattern, and since both while and rename apply the scalar context, the two globes return the same value at each iteration.

 while (<*.JPG>) { s/JPG$/jpg/; rename <*.jpg>, $_; } 

In the first iteration of the $_ while , the value of IMG_0178.JPG set while , and the substitution sets the file type to lowercase.

Then, in renaming <*.JPG> is executed in a scalar context and returns IMG_0178.JPG again - the first file in the same list, because the Windows file names are not case sensitive.

So, renaming is done by rename 'IMG_0178.JPG', 'IMG_0178.jpg' as needed.

The rewriting of rename , like this, shows it 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're in luck, and your files should have been renamed at your request.

But do not do it. In particular, you should run a program with print instructions instead of any critical operations so that you can see what happens.

That would be better, since id more clearly does what is supposed

 perl -e '($f = $_) =~ s/JPG$/jpg/i and rename $_, $f while <*.JPG>' 
+4
source

All Articles