Renaming lots of files in Linux according to a pattern

I haven't tested these, so I put echo at the front of the commands so you can try them before removing the echo to run them for real.

  1. for f in *v9.zip; do echo mv "${f}" "${f%v9.zip}.zip"; done
    
  2. for f in *_*; do echo mv "${f}" "${f//_/-}"; done
    

As for your third problem I'm sure it can be done too but maybe a more sophisticated approach than raw shell one-liners will help, as @tchrist mentioned.


There's a rename command provided with most Debian/Ubuntu based distros which was written by Robin Barker based on Larry Wall's original code from around 1998(!).

Here's an excerpt from the documentation:

  "rename" renames the filenames supplied according to the rule specified as the first argument.  The perlexpr argument is a Perl expression which is expected to modify the $_ 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 "*.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/' *

It uses perl so you can use perl expressions to match the pattern, in fact I believe it works much like tchrist's scripts.

One other really useful set of tools for bulk file renaming is the renameutils collection by Oskar Liljeblad. The source code is hosted by the Free Software Foundation. Additionally many distros (especially Debian/Ubuntu based distros) have a renameutils package with these tools.

On one of those distros you can install it with:

$ sudo apt-get install renameutils

And then to rename files just run this command:

$ qmv

It will pop open a text editor with the list of files, and you can manipulate them with your editor's search and replace function.


My favorite solution is my own rename script. The simplest example that maps to your problems are these:

% rename 's/_/-/g' *
% rename 's/(\p{Lower})(\p{Upper})/$1 $2/g' *

Although I really hate whitespace in my filenames, especially vertical whitespace:

 % rename 's/\s//g' *
 % rename 's/\v//g' *

et cetera. It’s based on a script by The Larry Wall, but extended with options, as in:

usage: /home/tchrist/scripts/rename [-ifqI0vnml] [-F file] perlexpr [files]
    -i          ask about clobbering existent files
    -f          force clobbers without inquiring
    -q          quietly skip clobbers without inquiring
    -I          ask about all changes
    -0          read null-terminated filenames
    -v          verbosely says what its doing 
    -V          verbosely says what its doing but with newlines between old and new filenames
    -n          don't really do it
    -m          to always rename
    -l          to always symlink
    -F path     read filelist to change from magic path(s)

As you see, it can change not just the names of files, but where symbolic links are pointing to using the same pattern. You don’t have to use a s/// pattern, although often one does.

The other tools in that directory are mostly for Unicode work, of which there are some super-useful ones.

Tags:

Linux

Sysadmin