How to batch rename sequentially prefixed numbers to new sequential prefixes via terminal?
How can I batch rename, using the terminal, a set of files where multiple numbers share the same prefix so that all those prefixes are set to new ones?
For example:
011.foo.txt -> 001.foo.txt
011.bar.psd -> 001.bar.psd
011.baz.gif -> 001.baz.gif
012.qux.js -> 002.qux.js
012.corge.png -> 002.corge.png
...
020.thud.txt -> 010.thud.txt
I'd like to use the rename command if possible:
rename [ -h|-m|-V ] [ -v ] [ -0 ] [ -n ] [ -f ] [ -d ] [ -e|-E perlexpr]*|perlexpr [ files ]
Really appreciate your help figuring this out, Thanks!
Using the perl rename
as requested.
For what your question demonstrates:
rename -n 's/^(\d+)/sprintf "%03d", $1-10/e' *
dry-run output:
rename(011.bar.psd, 001.bar.psd)
rename(011.baz.gif, 001.baz.gif)
rename(011.foo.txt, 001.foo.txt)
rename(012.corge.png, 002.corge.png)
rename(012.qux.js, 002.qux.js)
rename(020.thud.txt, 010.thud.txt)
For what the question title says, with actual sequential prefixes:
rename -n -E 'use vars q{$n}' -e 's/^(\d+)/sprintf "%03d", ++$n/e' *
rename(011.bar.psd, 001.bar.psd)
rename(011.baz.gif, 002.baz.gif)
rename(011.foo.txt, 003.foo.txt)
rename(012.corge.png, 004.corge.png)
rename(012.qux.js, 005.qux.js)
rename(020.thud.txt, 006.thud.txt)
For the first one, if you don't want to hardcode the delta 10
:
rename -n -E 'use vars q{$delta}' -e '
s{^(\d+)}{
$delta = $1 - 1 unless defined $delta;
sprintf "%03d", $1 - $delta
}e
' *
If you want files with the same original prefix to map to the same prefix in the new scheme without relying on subtraction, then you could do so by creating a hash (associative array) of the prefixes, numbering those sequentially, then performing the rename substitutions by lookup in the hash. Ex.
$ rename -n -E '
BEGIN {
my $n = 1;
our %pfxs;
foreach my $f (@ARGV) {
$pfxs{$1} = (exists $pfxs{$1} ? $pfxs{$1} : $n++) if $f =~ /^(\d{3})/
}
}
our %pfxs;
s/^(\d{3})/sprintf "%03d", $pfxs{$1}/e
' [0-9][0-9][0-9].*
rename(011.bar.psd, 001.bar.psd)
rename(011.baz.gif, 001.baz.gif)
rename(011.foo.txt, 001.foo.txt)
rename(012.corge.png, 002.corge.png)
rename(012.qux.js, 002.qux.js)
rename(020.thud.txt, 003.thud.txt)
Since it doesn't rely on subtraction, this method can be used even when the original prefixes are non-numeric.
This can undoubtedly be improved - in particular, one could check the max value of $n
at the end of the mapping and choose the width of the output accordingly.