Rename a group of files at once
One thing I need to do pretty much every day, is rename a batch of files, using a set of predetermined rules. A few months back, when I was still on Windows, I used to have a tool to do just that, so logically I started looking for a "replacement" now that I'm on Linux.
However, while I did find a few batch renaming utilities, none of them would really fill all the checkboxes of my requirements list. Either because they didn't provide the "rules" I was looking for, or because they would rename files after each rule has been applied, or because they couldn't be used from scripts (that way I wanted), or whatever the reason.
So, I just went ahead and made (yet another) one:
molt: batch renaming utility
As said, the aim of this little tool is to rename a group of files, using a set of rules.
molt will, for each file, apply all the rules to determine the new name. It will make sure those new names are "free," as in not already in use; and handles "avoidable conflicts" - when a file's new name is taken by another file to be renamed (performing two-steps renaming with a temporary name if needed).
By default, molt will only attempt to rename anything if no errors or conflicts
were found (though this could be changed via option --continue-on-error
)
Rules
Rules are the heart of molt, since they're what determines the new names will be. molt comes in with a few rules, currently they are:
--upper
: convert to upper case
--lower
: convert to lower case
--camel
: convert to Camel Case
--list
: use list of new news read from stdin
--sr search[/replacement[/options]]
: perform (optionally case insensitive)
search and replace operation. Removes search if no replacement is specified
--regex pattern[/replacement[/options]]
: same as above, but using regular
expressions
--vars
: resolves variables
--tpl template
: set all filenames to template
and, so it's actually useful,
resolves variables
That's it, but I might add a few more, such as ways to insert a string at a given place, and maybe remove a string by location as well. (And if you have needs/ideas for rules, let me know.)
Another thing to note: molt comes with plugin support, which can provide new rules.
Variables
You can use "variables" in the new flenames, which will be resolved
independently for each file. The syntax is to put the variable's name in between
dollar signs, e.g: $FOOBAR$
Some variables can also support optional parameters. Those can be specified
using colon as separator, e.g: $FOOBAR:PARAM1:PARAM2$
Variables are not automatically resolved, you need to use the rule --vars
in
order to have them resolved, which gives you the ability to determine when
resolving happens, as well as continue processing with more rules afterwards.
Currently molt only supports one variable :
NB[:digits[:start[:increment]]]
: resolves to a number, starting at start
(default: 1) and incremented by increment
(default: 1; can be negative) for
each file using it. The number will have at least digits
digits, padded with
zeros.
This means that is you use the variable on only some of the files (e.g. through
a rule like --sr
) then counter will only be incremented for each of those
files, "skipping" the files whose name doesn't include the variable.
However, if used multiple times within the same name, it'll only be incremented once.
As with rules, plugins can provide new variables as well. Speaking of which,
plugin: magicvar
molt comes with plugin support, so new rules and/or variables can be added easily. And since I wanted to make one, both as an example and a way to make sure the whole thing worked as expected, molt comes with a plugin called magicvar.
What it does is provide a new variable, whose name is a underscore. The idea is that this variable requires one parameter, which is the "actual name" of the variable you want to include. And resolving it will be done through an external process.
For example, let's say you want to be able to use a variable "type" to get the
type of file, as returned by command file
First you need to create a configuration file, in ~/.config/molt/magicvar.conf
and within section variables
you define which command line shall be run to
resolve the variable. You can use %F
as placeholder for the path/filename of
the file, as well as %P
for any additional parameters given to the magic
variable (in molt's new name).
For example, with:
[variables]
type=file -b %F
Then, using $_:type$
in molt will have magicvar run file -b
for each file,
and use its output as value for the variable (auto-stripping the trailing \n).
This could e.g. be used to get EXIF data from pictures, ID3 tags from MP3 files, that sort of things. (Although a dedicated plugin might be better/faster, especially since it could cache data, to e.g. read the file once for all possible variables.)
Output & return value
molt provides two outputs that can be of use from scripts: only the new names of files (or, if they haven't - or couldn't - be renamed, their current names), or both their old and new names.
It returns 0 in case of success, else uses bit fields with the following :
1 Syntax error (e.g. invalid option, etc)
2 File not found
4 Rule failed
8 Invalid new name
16 New name already in use
32 Internal conflict (multiple files with the same new name)
64 Rename operation failed
Important
molt is not an advanced mv
, it is a (batch) renaming utility, and as such only
ever tries to rename files (whereas mv can also effectively move files).
While with certain options it can also seems like it moves file, this will only work if said files remain on the same file system. Trying to have a file moved to another file system is likely to fail with an error such as "Invalid cross-device link"
Download
There you go. Hopefully this might be useful to some. molt is released under GNU GPL v3+ The source code is available on this BitBucket repository.
You can also find a PKGBUILD in the AUR.
And of course bug reports, suggestions or any other form of constructive criticism is very much welcome.