Batch rename files in Linux

Solution 1:

Basically, you can use the rename tool for that. It should come in a Perl-based version with Debian-based Linux distros, but you can easily download it from source as well (obviously, you need to make it executable first with chmod +x).


The following command will replace the _full part with _500 on all JPG files in the current directory.

rename 's/_full/_500/' *.jpg

To do this recursively, starting from your current directory, use rename with find.

find . -type f -iname "*.jpg" -exec rename 's/_full/_500/' {} \;

Note: You may want to test the command before actually executing is. In order to do that, add the -n option to rename (e.g. between rename and the 's//' string).

Solution 2:

You may want to look into zmv. zmv is a zsh specific feature, and requires autoload -U zmv to be somewhere in your .zshrc file.

EDIT: As an example, the task the OP posed could be solved with

noglob zmv '(*)_full.(*)' '$1_500.$2'

An excerpt from the zshcontrib man page:

zmv [ -finqQsvwW ] [ -C | -L | -M | -p program ] [ -o optstring ] srcpat dest

Move (usually, rename) files matching the pattern srcpat to corresponding files having names of the form given by dest, where srcpat contains parentheses surrounding patterns which will be replaced in turn by $1, $2, ... in dest. For example,

zmv '(*).lis' '$1.txt'

renames foo.lis to foo.txt, my.old.stuff.lis to my.old.stuff.txt, and so on.

The pattern is always treated as an EXTENDED_GLOB pattern. Any file whose name is not changed by the substitution is simply ignored. Any error (a substitution resulted in an empty string, two substitutions gave the same result, the destination was an existing regular file and -f was not given) causes the entire function to abort without doing anything.

EXTENDED_GLOB patterns are tremendously powerful. Here is a good primer on the concept.