What is the best way, using Bash, to rename files in the form:
(foo1, foo2, ..., foo1300, ..., fooN)
With zero-padded file names:
(foo00001, foo00002, ..., foo01300, ..., fooN)
What is the best way, using Bash, to rename files in the form:
(foo1, foo2, ..., foo1300, ..., fooN)
With zero-padded file names:
(foo00001, foo00002, ..., foo01300, ..., fooN)
In case
N
is not a priori fixed:It's not pure bash, but much easier with the
rename
command:Pure Bash, no external processes other than 'mv':
I had a more complex case where the file names had a postfix as well as a prefix. I also needed to perform a subtraction on the number from the filename.
For example, I wanted
foo56.png
to becomefoo00000055.png
.I hope this helps if you're doing something more complex.
The oneline command that I use is this:
PATTERN can be for example:
%04d.${f#*.}
(keep original file extension)photo_%04d.${f#*.}
(keep original extension)%04d.jpg
photo_$(basename $f .${f#*.})_%04d.${f#*.}
You can filter the file to rename with for example
ls *.jpg | ...
You have available the variable
f
that is the file name andi
that is the counter.For your question the right command is:
My solution replaces numbers, everywhere in a string
You can easily try it, since it just prints transformed file names (no filesystem operations are performed).
Explanation:
Looping through list of files
A loop:
for f in * ; do ;done
, lists all files and passes each filename as$f
variable to loop body.Grabbing the number from string
With
echo $f | sed
we pipe variable$f
tosed
program.In command
sed 's/[^0-9]*//g'
, part[^0-9]*
with modifier^
tells to match opposite from digit 0-9 (not a number) and then remove it it with empty replacement//
. Why not just remove[a-z]
? Because filename can contain dots, dashes etc. So, we strip everything, that is not a number and get a number.Next, we assign the result to
number
variable. Remember to not put spaces in assignment, likenumber = …
, because you get different behavior.We assign execution result of a command to variable, wrapping the command with backtick symbols `.
Zero padding
Command
printf "%04d" $number
changes format of a number to 4 digits and adds zeros if our number contains less than 4 digits.Replacing number to zero-padded number
We use
sed
again with replacement command likes/substring/replacement/
. To interpret our variables, we use double quotes and substitute our variables in this way${number}
.The script above just prints transformed names, so, let's do actual renaming job:
Hope this helps someone.
I spent several hours to figure this out.