Bulk file rename using regular expressions on Windows

This article describes a few methods of bulk renaming of files using Regular Expressions. The first two run in batch mode from the Windows console, the third is an interactive application.

Method 1: scripting sed using a bat file

 

@echo off
============ ========================= ===================== =================== =======
rem Copyright: Owen Duffy, 2015. All rights reserved.
rem A batch file for RE based file rename.
rem Uses sed, see http://gnuwin32.sourceforge.net/packages/sed.htm .

rem test for command extensions
if "~x0"=="%~x0" goto EXTERROR 
if "%%~x0"=="%~x0" goto EXTERROR
if not CmdExtVersion 2 goto EXTERROR

rem start
set SED=sed

rem deal with options
if not #%1==#-n goto getsedexpr
set noaction=y
shift
echo Trial run only, rename disabled.

rem get the sedexpr string
:getsedexpr
set sedexpr=%1
shift
if #%sedexpr%==# goto usage

for %%f in (%1 %2 %3 %4 %5 %6 %7 %8 %9) do call :dosed "%%f"
goto cleanup

:dosed
rem extract old filename+ext
for %%f in (%1) do set oldname="%%~nf%%~xf"
rem extract rename arguments
for /f "usebackq tokens=*" %%n in (`echo %oldname% ^| %SED% -r -e %sedexpr%`) do call :doren %1 %%n %oldname%
exit /b

:doren
if %2==%3 exit /b
echo rename %1 %2
if not #%noaction%==#y rename %1 %2
exit /b

:ERREXIST
echo cannot rename %1 as %2% as %2 exists.
exit /b

:usage
echo Usage: srename [-n] sedexpr [filenames]
echo.
echo sedexpr is a sed s/// command using extended RE.
echo Example: srename s/\"(.*)\.(.*)\"/"\2.\1"/ *.*
echo.
goto cleanup

:cleanup
set sedexpr=
set SED=
set noaction=
goto eof

:EXTERROR
echo:This script requires command extensions v2 or later!>&2
verify error 2>NUL
goto eof

:eof

 

A Windows port of sed can be downloaded from http://gnuwin32.sourceforge.net/packages/sed.htm .

Method 2: scripting PERL using a bat file

The rename.pl script derived from Larry’s Wall’s original is now installed in the Debian distribution. If you have PERL installed on Windows, then you need a bat file wrapper to perform the file globbing that is done by the shell on unix but not done by the Windows console command processor.

PRENAME.BAT:

@echo off
rem Copyright: Owen Duffy, 2015. All rights reserved.
rem A Windows front end for the PERL rename script

rem test for command extensions
if "~x0"=="%~x0" goto EXTERROR 
if "%%~x0"=="%~x0" goto EXTERROR
if not CmdExtVersion 2 goto EXTERROR

rem start
set PRENAME=\bin\rename.pl

rem generate a unique workfile name
:tryworkfileagain
set /a workfile=%RANDOM%+100000
set workfile=%TEMP%\prename-%workfile:~-4%.tmp
if exist %workfile% goto tryworkfileagain

rem parse the options
set options=
:nextoption
set arg=%1
if #%1==# goto usage
set arg=#%arg:~0,1%

if not %arg% == #- goto getperlexpr
set options=%options% %1
shift
goto nextoption

rem get the perlexpr string
:getperlexpr
rem shift
set perlexpr=%1
shift
if #%perlexpr%==# goto usage

for %%f in (%1 %2 %3 %4 %5 %6 %7 %8 %9) do echo %%f >>%workfile%
perl %PRENAME% %options% %perlexpr% <%workfile%
goto cleanup

:usage
echo Usage: prename [-v] [-n] [-f] perlexpr [filenames]
goto cleanup

:cleanup
if exist %workfile% del /q %workfile%
set options=
set perlexpr=
set workfile=
set PRENAME=
goto eof

:EXTERROR
echo:This script requires command extensions v2 or later!>&2
verify error 2>NUL
goto eof

:eof

rename.pl:

#!/usr/bin/perl -w
#
#  This script was developed by Robin Barker (Robin.Barker@npl.co.uk),
#  from Larry Wall's original script eg/rename from the perl source.
#
#  This script is free software; you can redistribute it and/or modify it
#  under the same terms as Perl itself.
#
# Larry(?)'s RCS header:
#  RCSfile: rename,v   Revision: 4.1   Date: 92/08/07 17:20:30 
#
# $RCSfile: rename,v $$Revision: 1.5 $$Date: 1998/12/18 16:16:31 $
#
# $Log: rename,v $
# Revision 1.5  1998/12/18 16:16:31  rmb1
# moved to perl/source
# changed man documentation to POD
#
# Revision 1.4  1997/02/27  17:19:26  rmb1
# corrected usage string
#
# Revision 1.3  1997/02/27  16:39:07  rmb1
# added -v
#
# Revision 1.2  1997/02/27  16:15:40  rmb1
# *** empty log message ***
#
# Revision 1.1  1997/02/27  15:48:51  rmb1
# Initial revision
#

#use strict;

use Getopt::Long;
Getopt::Long::Configure('bundling');

my ($verbose, $no_act, $force, $op);

die "Usage: rename [-v] [-n] [-f] perlexpr [filenames]\n"
    unless GetOptions(
    'v|verbose' => \$verbose,
    'n|no-act'  => \$no_act,
    'f|force'   => \$force,
    ) and $op = shift;

$verbose++ if $no_act;

if (!@ARGV) {
    print "reading filenames from STDIN\n" if $verbose;
    @ARGV = ;
    chop(@ARGV);
}

for (@ARGV) {
    my $was = $_;
    eval $op;
    die $@ if $@;
    next if $was eq $_; # ignore quietly
    if (-e $_ and !$force)
    {
    warn  "$was not renamed: $_ already exists\n";
    }
    elsif ($no_act or rename $was, $_)
    {
    print "$was renamed as $_\n" if $verbose;
    }
    else
    {
    warn  "Can't rename $was $_: $!\n";
    }
}

__END__

=head1 NAME

rename - renames multiple files

=head1 SYNOPSIS

B S<[ B<-v> ]> S<[ B<-n> ]> S<[ B<-f> ]> I S<[ I ]>

=head1 DESCRIPTION

C
renames the filenames supplied according to the rule specified as the
first argument.
The I 
argument is a Perl expression which is expected to modify the C<$_>
string in Perl for at least some of the filenames specified.
If a given filename is not modified by the expression, it will not be
renamed.
If no filenames are given on the command line, filenames will be read
via standard input.

For example, to rename all files matching C<*.bak> to strip the extension,
you might say

    rename 's/\.bak$//' *.bak

To translate uppercase names to lower, you'd use

    rename 'y/A-Z/a-z/' *

=head1 OPTIONS

=over 8

=item B<-v>, B<--verbose>

Verbose: print names of files successfully renamed.

=item B<-n>, B<--no-act>

No Action: show what files would have been renamed.

=item B<-f>, B<--force>

Force: overwrite existing files.

=back

=head1 ENVIRONMENT

No environment variables are used.

=head1 AUTHOR

Larry Wall

=head1 SEE ALSO

mv(1), perl(1)

=head1 DIAGNOSTICS

If you give an invalid Perl expression you'll get a syntax error.

=head1 BUGS

The original C did not check for the existence of target filenames,
so had to be used with care.  I hope I've fixed that (Robin Barker).

=cut

Method 3: RegexRenamer

RegexRenamer is a dedicated GUI app that allows the user to interactively construct the regular expressions whilst viewing the effect on the file list window.

Screenshot - 08_09_2015 , 17_59_15

Above is an example screenshot.