Recursively Renaming Multiple Files

I needed to rename a bunch of files for a customer at work the other day -- more than 60 files. The files were on a Linux system, so I knew there was an easy way of doing it. A few days ago I used perl to search and replace a piece of text in a several files , so I decided to find a way to do it with perl.

I found the following script on this site:

[perl]
#!/usr/local/bin/perl
#
# Usage: rename perlexpr [files]

($regexp = shift @ARGV) || die "Usage: rename perlexpr [filenames]n";

if (!@ARGV) {
@ARGV = ;
chomp(@ARGV);
}

foreach $_ (@ARGV) {
$old_name = $_;
eval $regexp;
die $@ if $@;
rename($old_name, $_) unless $old_name eq $_;
}

exit(0);
[/perl]

After saving the script to a file called rename (and chmod 755'ing it) I was able to run the following command to change the file extension on all .JPG files from uppercase to lowercase .jpg. To search for all files underneath a particular directory, I used the find command and piped it's output to the rename script:

find /home/customername/content/images/ | rename 's/JPG$/jpg/'

A few seconds later and all the files were renamed! This script is incredibly versatile, as you can pass it any regular expression! A few quirks I found were that you cannot reference the script; you must use it from the directory you stored it in (find / | ~/rename 's/JPG$/jpg/' won't work). This is because the script uses itself (on line 17). This also means if you save the script as something other than rename, you must also modify line 17 of the script.

Write a Comment

Comment

  1. I have been using this… pretty close to what you have been using, only you do not need to create the rename file:

    find . -type f -exec perl -e ‘$new=$ARGV[0]; $new =~ s/myOLD_PATTERN/myNEW_PATTERN/; rename($ARGV[0],$new);’ {} ;

    it uses perl, and perl’s rename.

    watch out for special characters in the patterns (so a “.” should be a “.”

    note: i hope this is still relevant to you, since i did not see a date on this post…

    • Thanks, Fawzi! This was written a few years ago, but I get traffic from Google all the time so I’m sure someone will find your tip helpful! 🙂

  2. it’s been a while, but how about this?

    renames directories (changes space to underscore):

    find . -type d -print0 | xargs -0 rename -v ‘y/ /_/’

    if you change “d” to “f” then renames files using the given pattern