Dynamic Renamer

The following script is a dynamic renamer that performs one or more transformations in arbitrary order. You don't have to modify the script to change the rename behavior - instead, you just specify the transformations you want performed in the DOpus Rename New name field. If you want to save the sequence, just save it to a new Preset and you can recall it again later. This helps you build a rename script live for use in the Rename dialog or in a button.

The transformation operations are listed below, and are specified as short flags. Each flag performs a simple transformation. Adding additional flags creates a chaining of transformations, allowing the building of complex renames very quickly and easily. Flags perform the transformations in order they are specified, so this allows maximum control over when a transformation should occur.

As you add each transformation flag to the New name field, the Preview window will show you how a flag affects the file name.

version: 1.12


  • -c case;
    follow with any of ulULtT (u=upper or l=lower first, U or L all, t=titlecase, or T=titlecase strict)

  • -d date append/prepend;
    format: -d/outspec/ or -d/inspec/outspec/ (-D prepends), *spec is a strftime template;
    default outspec: -d: '%d-%m-%Y', -D: '%Y-%m-%d '; inspec is pulled from filename between %% and %% (use a transform to insert them first)

  • -dd date guessing;
    format: -dd or -dd/outspec/, *outspec uses printf formats in Date::Manip::date

  • -e exclude files matching pattern;
    format: -e/RE/ use -E to ignore suffix

  • -f files or folders only: f=files-only, F=folders-only

  • -h html to ascii

  • -k kill text after (-k) or before (-K) specified string, inclusively (default) or exclusively: -k/string/[ei] -K=before optional: e=exclude, i=ignore case

  • -r replace;
    format: -r/oldstr/newstr/gie
    optional: g=global, i=ignore case, e=evaluate newstr as perl code

  • -rr replace range;
    format: -rr/<range>/newstr/, rr=front, RR=rear; replace range of chars with newstr, is either m or m-n and m <= n

  • -R reverse;
    format: -R/oldsep/newsep/ reverse words using oldsep string replaced w/newsep string; empty oldsep reverses characters; empty newsep uses oldsep

  • -s suffix change,
    format: -s[lun] lowercase (default), uppercase, none

  • -S sort;
    format -S/oldsep/newsep/r sort words using oldsep string replaced w/newsep string; empty oldsep reverses characters; empty newsep uses oldsep;
    optional: r=reverse sort

  • -t transliteration;
    format: -t/srchlist/tolist/cds
    optional: c=compliment srch list, d=delete found but unreplaced, s=squash dups

  • -u uri unescape

  • -U Unicode to ASCII

  • -w whitespace spans to single space

  • -x trim characters;
    format: -x[[=]n], x=front, X=rear; optional: n=number of chars (defaults to 1); '=' means leave n chars

  • -z zero pad number;
    format: -zn, where n is final number of 0-padded digits

  • -# number; increase #'s for padding or more digits;
    flags [r^] r=random, ^=numbers in front

  • -/ regular expression substitution;
    format: -/RE/replacement/gie
    optional: g=global, i=ignore case, e=eval expression

  • -^ append text at beginning;
    format: -^/text/

  • -$ append text at end;
    format: -$/text/

  • -+ add 1 (or n) to final numeric sequence;
    format: -+n optional n may be negative


As an example, in the following transformation:

-u -h -s -b -a/El/ -cu -r/-/_/g -w

  • -u flag replaces URI escapements (%20, etc.) with standard characters,
  • -h replaces html entities,
  • -s then lowercases the file suffix,
  • -b then removes any bracketed content including the brackets,
  • -a moves articles to the end including the user-defined "El" article,
  • -cu uppercase the first word of the filename,
  • -r replaces dashes with underbars globably (g flag), and
  • -w finally cleans excessive whitespace.

I'll add more functions as people request them.


The script requires ActivePerl. Use version (not It is free, safe, easy, and non-invasive to install. Get the 32-bit or 64-bit installer as appropriate for your version of Windows:

ActivePerl 64-bit
ActivePerl 32-bit

Why did I use Perl? It is an exceptionally fast, rich, power scripting language that was designed to tasks such as this. Most transformations are a couple of lines of code - adding new functionality is very easy, so feel free to ask.

Note: Version 1.11 requires a module update in ActivePerl. After installing ActivePerl, open a Windows command shell, and enter the command:

ppm install date-manip

and hit Enter. When the update is complete, you can exit out of the command shell. If you already have the date-manip module installed, use:

ppm update date-manip


To install the Dynamic Renamer rename script, download the latest zip file below, unzip it, and then open Directory Opus' Rename dialog, and use its File > Import menu item, and select the Dynamic Renamer .orp file.

Comments welcome, assistance provided.
_Dynamic Renamer 1.12.zip (7.27 KB)
_Dynamic Renamer 1.11.zip (6.19 KB)


I'll update this post with the change list.

version 1.12
New: The E flag to the -c case transformation supports elision.
New: The f flag to -dd date-guessing allows dates in future.
New: The -r replacement transformation supports global, case-ignored, and perl-code evaluations with flags -g, -i, and -e respectively.
New: Support numeral systems in -# number transformation. Supply a number base from 1 to 36 (e.g. -###16 outputs hex numbers).
Fix: Date guessing -dd is a bit smarter.
Change: The -R global replacement transformation was removed (use instead the -r transformation with the g flag).

version 1.11
New: Date guessing use -dd or -dd/date spec/. The -dd transformation will attempt to detect a date in a filename, and reformat it according to the specified date spec template or the built in default of YYYY-MM-DD.
New: Range replace transformation can now work from the end. Use -RR instead of -rr.

* See Note in first post.

version 1.10
New: Range replace transformation -rr//newstr/ will replace characters at the positions specified by with the string newstr. A range is specified as either m, or m-n, where m and n are two integers and m <= n.
New: The -x trim option now can now leave a specified number of characters (trims all but n characters). -X=2 trims all but the first two characters, and -x=3 trims all but the last three characters.

version 1.9
Fix: Resolved a long-standing problem with some tricky Unicode characters being treated like their ASCII doppelgangers. This script is also instructive on how to properly receive and return Unicode from DOpus via ActivePerl.

version 1.8
New: RE substitution (-/) has a new 'e' flag, which causes evaluation of perl code in the replacement side.
New: Zero pad a number to the specified number of digits. Example: -z3 converts 5, 13, 100 to 005, 013, 100.
Fix: Problem obtaining file name for non-suffixed files whose names contained a dot.

version 1.7
New: Kill text after (-k) or before (-K) specified string, inclusively (default) or exclusively: -k/string/[ei] -K=before optional: e=exclude, i=ignore case.
New: Added r flag to -# for random value; add # characters to increase random number size (0 to 10^n - 1).
Fix: Ignore transformations if no filename remains.
Fix: Handle non-suffixed filenames

version 1.6
New: Trim n characters from front or back; -x[n], -X[n].
New: Files or folders only: -f, -F.
New: Reverse words using arbitrary separator string which is replaced with a new separator string; empty separator reverses characters; empty new separator retains old separator: -R/oldsep/newsep/.
New: Sort words using arbitrary separator string which is replaced with a new separator string; empty separator sorts characters; empty new separator retains old separator: -S/oldsep/newsep/r optional r flag reverses sort.
Change: Replace mode -r now uses g=global and i=ignore case flags.
Change: Reverse globally -R option now used for Reverse (for global replace, use -r/old/new/g).
Change: Article transformation will ignore leading punctuation.

version 1.5
New: Append text (more easily) at beginning or end: -^/text/ and -$/text/.
New: Add 1 (or n) to final numeric sequence: -+n optional n may be negative
New: Strict title case (lower case prepositions, articles, conjunctions): -cT
Fix: Fix possible bug with article removal

version 1.4
New: New suffix modification format -s[lun] for l=lowercase (default), u=uppercase, or n=none.
New: Flexible filename date parsing and output. Any date surrounded by %% and %% can be parsed within the filename and output in some other format (format: -d/inspec/outspec/, where inspec is any strptime format and outspec any strftime format). First use a transformation to surround the date/time in the filename with a pair of %% characters, and then specify a format template for inspec that matches the filename's date and time, and specify a different output format as outspec. Locale-specific names are understood. See example below.
Fix: Sanitize filenames where necessary
Change: -S (suffix uppercase) depricated; see new suffix format above.

Example date from filename parsing

  filename:       AC 1-23-13 New Haven Expense Rpt.pdf
  transformation: -r/AC /%%/ -r/ /%%/ -D/%m-%d-%y// -R/ Expense Rpt//
  result:         2013-01-13 New Haven.pdf

  filename:       2-9-2013.txt
  transformation: -/(.*)/%%$1%%/ -d/%m-%d-%Y/%Y\%B\%A/
  results:        2013\February\Saturday.txt

version 1.3
New: Folders can now be renamed
Fix: Needed to set Old name to (.*) so DOpus won't complain.
Change: In date/time, replace / and : with - and ., respectively

version 1.2
New: Unicode to ASCII: -U
New: Date append/prepend using strftime formatting specs: -d appends, -D prepends
New: Articles to end (-a), or strip (-A). User-defined article can be specified
Fix: Only the first -e exception was working

version 1.1
New: Added transliteration: -t
New: Exclude files matching pattern: -e and -E
New: Added upper/lower first/all cases: -c[uUlLt]
Change: Change case flag to -c
Change: Change title case flag to -ct
Fix: Flag parser handles embedded spaces inside / /

The -e option is very cool. Many folks have asked for a way to skip certain files within Rename. You can now define a pattern to skip files already selected.

Is this what you are talking about:

ActivePerl Downloads - Perl Binaries for Windows, Linux and Mac

Is there any reason for not providing that link here?

As to "easy to install", you may over estimate the skills of some of us. Well, me. So a pointer to simple instructions would also help.

There are always reasons, but your request trumps mine. Link posted. Thanks!

A very useful addition to the DOpus arsenal of tools and tweaks. Thanks, Mr C.

Regards, AB


I just posted version 1.5 with a few more goodies. Aside from my own uses, I've been looking at the goals of the old rename scripts and have added that functionality in a more generalized fashion.

It seems that -A/xxx/ to remove a user defined article does not work when the article starts with an underscore.

Regards, AB

How about an option to strip N characters from the beginning or end of the name. In the same vein, would it be possible to strip to/from a user supplied string of characters, both inclusive and exclusive.

Regards, AB

So you think it should ignore initial punctuation? And then that punctuation should remain at the front?

_A Test File.txt --> _Test File.txt
_A Test File.txt --> _Test File, A.txt

I don't mind changing that.

Stripping to or from is done with RE substitution:

-/^.{4}// removes the first 4
-/.{3}$// removes the last 3

A user supplied string is just substitution with nothing:

-/user string//

add the g flag to do so globally.

And sometimes those reasons are good! Like lots of different options, or linking to "dodgy" places.

Which is why I asked. Wouldn't want to trample on toes.

Just posted 1.6. See changes.

Thanks for v1.6. The simple character remover -x is a lot easier for those of us whose brains are not natively wired for RegEx. :slight_smile:

My other earlier request was really for a "chop" function. Probably best served by example.

Let's assume -z as the leading operator and -Z for trailing.
Let's also assume that the default is inclusive chopping and that z+ and Z+ force exclusive chopping..

[b][i]-z/quick / : The quick brown fox.txt --> brown fox.txt
-Z/ brown/ : The quick brown fox.txt --> The quick.txt

-z+/quick / The quick brown fox.txt --> quick brown fox.txt
-Z+/ brown/ The quick brown fox.txt --> The quick brown.txt[/i][/b]

Regards, AB

P.S. No doubt there is also a simple (sic) RegEx solution to all of these.. :wink:

Ok, that sounds like a fine transformation.

I'm going to select -k as the flag (emacs users will understand k=Kill). Kill text after (-k) or before (-K) specified string, inclusively (default) or exclusively: -k/string/[ei] -K=before optional: e=exclude, i=ignore case.

If you want it now, you can add the following code anywhere as part of the if/else chain of transformations:

	elsif ($opt =~ s#^-([kK])/([^/]+)/([ie]*)##) {			# delete after/before
	    my ($mode,$pat,$flags) = ($1, "\Q$2\E", $3);
	    $excl = ($flags =~ s/e//g);
	    eval join('/', 's', $mode eq 'k' ? "^.*?($pat)" : "($pat).*\$", $excl ? '\1' : '', $flags);

Terrific! Another very useful addition. Well done, Mr C.

Regards, AB

EDIT: Nevermind, it really was a dumb question - RTFM. This worked to prepend a date in YYMMDD format:
-D/%y%m%d /

Thanks for this by the way, it's brilliant.

Dumb question, where do I go to change the date format used by the -d and -D operations?
I'm chasing a YYMMDD format.

On that note, is it possible to specify which template will be used with the -d or -D transformation if you have more than one template?



Version 1.11 adds a couple new capabilities (see the notes in this thread's second post).

The -dd transformation tries to detect a date within a filename and format it according to either the default specification or your own format supplied to the -dd transformation. The default output template is YYYY-MM-DD.

If you wanted year-only output, you'd use:


The detection is based on some pre-defined patterns at the top of the Dynamic Renamer code. These can be supplemented or amended as necessary. Not all dates can be easily detected (e.g. Sept 09), due to language and parsing ambiguities, but it tries to detect common cases. You may be able to use the -d transformation for some of these ambiguous cases.

In the version 1.11 update, I'd forgotten from my notes to update a usage message for the -r (replace) transformation. I've posted the correction in the first post above, and it will be available in the next update. It reads:

-r  replace; format: -r/oldstr/newstr/gie  optional: g=global, i=ignore case, e=evaluate newstr as perl code

The replace transformation accepts three optional flags at the end of the command which modify the default behavior as mentioned.

Note: Version 1.11 requires a module update in ActivePerl. After installing ActivePerl, open a Windows command shell, and enter the command:

   ppm update date-manip

and hit Enter. When the update is complete, you can exit out of the command shell.[/quote]

MrC - this update fails as shown on my W7-64 system and consequently v1.11 does not work.
v1.10 is OK with the same version of ActivePerl - ActivePerl-
I tried uninstalling and reinstalling ActivePerl. Same outcome.
Any suggestions?

Regards, AB

See if:

ppm install date-manip


You can run ppm with no arguments, and it will launch the GUI. Then, you can type date-manip into the search box; it should list version 6.46, which you can select to install if the command above for some reason didn't work (though, I'm not sure why it wouldn't).

In case anyone else falls foul of this, there were two problems..

[ol][li]I had installed ActivePerl to C:\Program Files\Perl64 (which is R/O) instead of the default C:\Perl64[/li][li]The date-manip package was not installed and so could not be updated[/li][/ol]
I uninstalled ActivePerl and reinstalled to the default location. That solved the R/O problem. I then used the PPM GUI to install date-manip and all is now well with v1.11.

Regards, AB