Skip to content
Advertisement

Bash oneliner to rename filenames

I often would like to easily rename a bunch of files. I always have to struggle with find, grep, xargs and sed to simply to the job. I would like to understand how I can do a better job using PCRE

Here my files:

$ find .
.
./08447.ctags
./10565.gitignore
./38037.inputrc
./42257.bashrc
./51395.gitk
./63705.gitconfig
./66352.octave_hist
./67049.ahk
./85869.vimrc
./89518.minttyrc
./desktop.ini
./dp4FontViewer64.exe
./SBZSwitcher_v1.8.9.7z
./xlive.rar

I would rename the dot files properly as I can do with this oneliner:

$ find . | grep -e '^[.]/[0-9]+[.]' | sed -r 's/^.*[.](w+)$/ .1/' | xargs -n2 mv

However I find this command very complicated and I am looking for something that I can easily use:

$ rename 's/^./d+.(w+)$/1/' .

My alternative solution was to write this Perl script:

#!/usr/bin/env perl
use 5.010;
use File::Find;

die "Wrong regexp!" unless
    $ARGV[0] =~ m/^
        s(?<delimiter>/|~|@|;|%|`||)
        (?<search>.*)
        (?&delimiter)
        (?<replace>.*)
        (?&delimiter)
        (?<flags>.*)$/x;

my $search = join('', map("(?$_)", split('', $+{flags}))).$+{search};
my $replace = '"'.$+{replace}.'"';
find(sub { rename($_, s/$search/$replace/ree) }, $ARGV[1]);

Is there any better solution?

Advertisement

Answer

There’s a simple solution.

If your rename command is fine but you want it recursive, then :

shopt -s globstar
rename 's/^./d+.(w+)$/1/' **

find -type f -exec rename 's/^./d+.(w+)$/1/' {} +

warning There are other tools with the same name which may or may not be able to do this, so be careful.

If you run the following command (linux)

$ file $(readlink -f $(type -p rename))

and you have a result like

.../rename: Perl script, ASCII text executable

and not containing ELF

then this seems to be the right tool =)

If not, to make it the default (usually already the case) on Debian and derivative like Ubuntu :

$ sudo update-alternatives --set rename /path/to/rename

(replace /path/to/rename to the path of your perl's rename command.


If you don’t have this command, search your package manager to install it or do it manually


Last but not least, this tool was originally written by Larry Wall, the Perl’s dad.

Advertisement