Skip to content
Fabio Mucciante edited this page Jun 17, 2022 · 12 revisions

Welcome to the filter_rename wiki!

FilterRename is a bulk renaming tool, based on the concept of filters as small operations to perform over a selected section of the filename or its metadata, these sections are called targets.

The main purpose is to create a command-line tool to rename files without missing any similar application offering a graphical interface which usually is way more comfortable to use to rename files but not enough to be run in a shell.

What filters are

The idea came from photographic applications which make use of filters as mini operations applied one by one to achieve the final result.

As we need to rotate, crop, adjust the color curve of our image file or in a portion of it, we might want to move words, delete them, replace a certain string, apply a counter and increase it, and so on...

Appending more of these small operations in a single command call we are able to completely transform the filename, not less not more than we would do manually for each file.

Once we get a satisfying setup we can collect them into groups called macros, which exist in the local configuration file, some of them are already defined in the global config file to be used as an example.

Filters in action

There are three basic filters, and the difference is in the way they accept the first parameter used to filter the portion of text that will be altered by the filter itself and, when requested, by the second argument provided:

Regular expression
the first parameter is considered a regular expression as intended by the Ruby interpreter, where needed also capturing groups are supported.
Word
the full string is considered a list of words separated by a configurable char (default is space ` `) and 1-based indexed. A word might contain also a single dash character separated by space by the other words.
Number
consecutive digits form numbers which are 1-based indexed depending on their position in the string. Remember that only numbers are considered in that index, so in a string of `5` words where the last is a number, the position of that number is still `1`.
Occurrence
Similar to the Regular Expression filters with the only difference is that this time the occurrences are counted one by one and altered taking their position into account. Think of this also as a generalization of the Number filters, where strings are the chunk of text to search.

The word, number and occurrence indexes allow also:

  • intervals (using a couple of dots .. as separator)
  • list of items (using a colon : as separator)
  • negative indexes starting from the end to the start (-1, -2, -3, ...)

Beside them there are filters which act with a different logic, here some examples:

  • prepend <TEXT> which prepends the TEXT to the current target;
  • prepend-from <TARGET> which is a shortcut for "template <TARGET><CURRENT-TARGET>";
  • template <STRING> which overwrite completely the current target with STRING replacing the placeholders, delmited by < and > with their respective targets;
  • select <TARGET> makes one of the available target the current target where apply the next filters;
  • set <TEXT>,[<TARGET>] fills the current or the optional TARGET with TEXT;
  • spacify <CHAR> replace the CHAR with a space
  • trim removes trailing spaces.

The role of targets

Splitting the filename in targets helps to better handle the logical parts to rename, and at the same time to easy recall themselves inside a template filter string.

The default target is name, until another target hasn't been selected with the select instruction, all the filters will be applied to that target.

Files with a particular format, like mp3, pdf, and jpeg, introduce more targets due to their metadata. Some of these metadata can also be overwritten (id3 tags in the mp3 files) others can only be used in read-only mode, embedding their value within a template string, surrounding their name with the angular braces < and >.

For each file, we can get the list of targets available using the targets command.

A small example

To give an idea about the whole process, let's consider these files:

  • image_20191224081015.jpg
  • image_20191224081507.jpg
  • image_20191225081803.jpg
  • image_20191225082101.jpg

executing the following command:

$ filter_rename image*.jpg --delete "\d{6}$" \
                           --replace-date "<Y><m><d>,<Y>-<m>-<d>" \
                           --spacify "_" \
                           --delete-word 1 \
                           --prepend "Christmas Vacations " \
                           --template "<name> #<count>" \
                           --format-number -1,2 \
                           --apply

We obtain:

  • Christmas Vacations 2019-12-24 #01.jpg
  • Christmas Vacations 2019-12-24 #02.jpg
  • Christmas Vacations 2019-12-25 #03.jpg
  • Christmas Vacations 2019-12-25 #04.jpg

What the list of filters did is explained here below:

  1. delete the last 6 digits
  2. replace the date in the format yearmonthday as year-month-day
  3. transform the underscore _ in space
  4. delete the first word
  5. prepend the current target string with "Christmas Vactions "
  6. rewrite the current target using the template "<name> #<count>" (the placeholders will be replaced by their respective values)
  7. format the last number as two digits number, prepending as many zeroes as needed.

Here below how the filename image_20191224081015.jpg evolved with every step:

  1. image_20191224.jpg
  2. image_2019-12-24.jpg
  3. image 2019-12-24.jpg
  4. 2019-12-24.jpg
  5. Christmas Vacations 2019-12-24.jpg
  6. Christmas Vacations 2019-12-24 #1.jpg
  7. Christmas Vacations 2019-12-24 #01.jpg

Operations

Operations are the commands that achieve the related tasks, only three of them are involved in the file renaming, the others just display the different configurations that filter_rename uses to implement the process.

A full list of them might be helpful to understand how to correctly apply the several options.

Renaming operations

preview (-p)
This is the basic operation executed by default, it only display the differences after the filters have been applied using the green and red colors to hilight them.
dry-run (-d)
This goes a step ahead simulating the renaming process and a symbol in the starting column quickly resume when: - the renaming raises some errors because of a filename conflict `[E]`; - didn't affect the file in any way `[X]`; - all the filters are successfully applied and the file will be renamed without errors `[V]`.
apply
This is the operation that performs the real renaming, in case of a conflict the file is simply skipped and an hash code for each file is printed to understand, wether or not, these files are identical.

Settings operations

--globals
Display the global settings which can be overriden using the *global* option, for example to change the *counter* length: `--global "counter_length:5"`
--configs
These settings are involved inside the filters and can be overriden with the *config* filter, for example to apply the next filter only to files starting with `a`: `--config grep:a.*`
--words
This shows the dictionary of words collected under groups and subgroups; groups represent the main domain, and inside the same group, words can be *translated* from a subgroup to another, a subgroup might be a language or simply a different logical partition.
--macros
Macros are collections of filters that provides the same transformation recall by the macro name, this operation display only the full list.
--show-macro MACRO
This operation goes in details displaying the list of instructions of a single macro.
--targets
For each file it prints the list of targets that can be reused inside the template or within those filters that require them to complete their task. They are printed in two lines: the read-only targets prefixed by a minus symbol `[-]` and the read-and-write prefixed by a plus symbol `[+]`. The only difference between these two types of targets remarks that the former, although transformed by the filters, won't be transferred to the physical file itself. So, for example, we can alter the *size* target but the file size will never be affected.