I have a ton of files, all named stuff like 1.jpg
, 2.jpg
, 3.jpg
, and so on up to 1439.jpg
, however, I have a problem with one of my projects and alphabetizing. It will usually go in the order 1.jpg
, 10.jpg
, 11.jpg
and so on.
What I need is some way to name the files so they are in the format such as 00001.jpg
all the way up to 01439.jpg
.
How would I be able to do this quickly and efficiently?
Ubuntu comes with a script called
rename
. It's just a little Perl script that features a number of powerful bulk-renaming features but the best (in this case) is the ability for it to run Perl during the replacement. The result is a truly compact solution:This is similar to the other
printf
-style answers here but it's all handled for us. The code above is for a 5-digit number (including a variable number of leading zeros).It will search and replace the first number-string it finds with a zero-padded version and leave the rest of the filename alone. This means you don't have to worry too much about carrying any extension or prefix over.
Note: this is not completely portable. Many distributions use
rename.ul
from theutil-linux
package as their defaultrename
binary. This is a significantly stunted alternative (seeman rename.ul
) which won't understand the above. If you'd like this on a platform that isn't using Perl's rename, find out how to install that first.And here's a test harness:
And an example prefixes (we aren't doing anything different):
Edit
Explanation:
if [[ $f =~ [0-9]+\. ]]
makes sure that only files whose names are numbers (followed by a dot) are being renamed.printf "%.5d" NUMBER
adds the leading zeroes"${f%.*}"
cuts the extension (.jpg) and leaves just the number.jpg
after the second backtick adds the file extension again.Note that this will work only on file names that are numbers. Left-padding leading zeroes to non-numbered files would require different format.
If you want to experiment try this command:
Edit 2
Made the command safer by making sure that only file names that are numbers are being renamed. Note that any pre-existing files named like 00001.jpg will be overwritten.
Below a python script.
The script adds leading zeros up to the defined number of digits. If the name is larger than that, the file(name) is untouched.
Combining different extensions in one rename action might add some convenience. To add extension(s), simply add them to the tuple, for example
extensions = (".jpg", ".jpeg", ".tiff")
.Copy the text into an empty file, save it as
rename.py
, enter the correct path to the files directory (sourcedir
), the number of digits you'd like the new names to have (number_ofdigits
) and the file extension(s) to rename (extensions
)Run it by the command:
The script:
edit:
Below a slightly improved version. It automatically determines the longest name in the directory, and adds leading zeros up to the length of the longest name.
example:
becomes:
No need to set the number of digits.
There is a rename utility implemented in Perl that makes this very easy:
The first argument is a Perl expression that is evaluated for each file name.
There is a GUI that will do this called pyRenamer which can be found in the repositories. Install, start, select your directory and just set the 'Renamed file name pattern' to '{num5}'on the 'Patterns' tab and click the 'Rename' button. You can also preview what will happen prior to renaming.
If by any chance your
rename
command is not perl-rename, you can use this perl code:When we say
foreach
we can refer to the files by$_
But you can install the propper
perl-rename
with this commandsAnother way of renaming these files easily is opening the folder with ranger file manager, select all files, run
:bulkrename
and use this vim command:I have also tried using ls + awk
Each string or number must be associated on the printf function, the result output will be something like this:
To really perform the renaming with this you have to add
| sh
at the end of it:The zsh shell has a loadable
zmv
module, similar to the external mmv command, and it also supports numeric ranges<m-n>
in its shell globs. So for instance given:then once the module is loaded as
you can do
where
(l:3::0:)
in the replacement variable expansion is a modifier that left pads to width 3 using string 0.Remove the
-n
flag once you are happy with the proposed renamings.This is crude, since it doesn't do the renaming intelligently, will need to think of a trick for that. But it should help you sort stuff.
Update: Well you have a more complete answer.