home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam    

UNIX Power Tools

UNIX Power ToolsSearch this book
Previous: 18.9 Renaming, Copying, or Comparing a Set of Files Chapter 18
Linking, Renaming, and Copying Files
Next: 18.11 Renaming Files with ren

18.10 There's More than One Way to Do It

[In article 18.9 , Jerry Peek shows how if you really understand the shell and utilities like sed , you can easily construct custom commands to change one set of filenames to another according to some regular pattern. In article 18.11 , Linda Mui explains a C program that makes the job easier - and has some built-in safeguards that prevent any renames if some of the moves could cause problems. Here, Larry Wall and Randal Schwartz present a Perl ( 37.1 ) script that gives you a different kind of power and flexibility. By the way, that's the Perl slogan: "There's more than one way to do it." -TOR ]

There are many ways of renaming multiple files under UNIX. Most of these ways are kludges. They force you to use ad hoc shell variable modifiers or multiple processes. With the rename Perl script, you can rename files according to the rule specified as the first argument. The argument is simply a Perl expression that is expected to modify the $_ string in Perl [the current input line -TOR  ] for at least some of the filenames specified. Thus you can rename files using the very same s/// notation you're already familiar with ( 34.24 ) . 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 *.bak to strip the extension, you might say:


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

But you're not limited to simple substitutions - you have at your disposal the full expressive power of Perl. To add those extensions back on, for instance, say this:


rename '$_ .= ".bak"' *

or even:


rename 's/$/.bak/' *

To translate uppercase names to lowercase, you'd use:


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

And how about these?


rename 's/foo/bar/; $_ = $was if -e' *foo*


find . -print | rename 's/readme/README/i'


find . -print | rename 's/$/.old/ if -M $_ > 0.5'


find . -name '*,v' -print | \
  rename 's#(.*)/#$1/RCS/#, $x{$1}++ || mkdir("$1/RCS", 0777)'

[Of course, to even understand some of these more complex incantations, you have to learn more about Perl, which is just the point... It's worth taking the time to learn. -TOR  ]

- LW , RS

Previous: 18.9 Renaming, Copying, or Comparing a Set of Files UNIX Power Tools Next: 18.11 Renaming Files with ren
18.9 Renaming, Copying, or Comparing a Set of Files Book Index 18.11 Renaming Files with ren

The UNIX CD Bookshelf Navigation The UNIX CD BookshelfUNIX Power ToolsUNIX in a NutshellLearning the vi Editorsed & awkLearning the Korn ShellLearning the UNIX Operating System