Skip to content

Built in variables

Ayooluwa Isaiah edited this page Feb 2, 2023 · 29 revisions

F2 provides support for variables that can be utilised in the replacement string. Variables are used to retrieve information from each file so that they are subsequently inserted in the new filename.

Note: Capture variables are also supported but discussed separately.

How variables work

Anything within two curly braces ({<var>}) is interpreted as a variable. Older versions of F2 required two curly braces on each side ({{<var>}}) but this was been simplified to just one from v1.9.0 though the older syntax is still supported.

This section will give a general overview of how variables work in F2. The explanation below assumes that the current working directory is house-chores with the following contents:

house-chores/
├── cleaning.md
├── laundry.md
├── mowing.md
└── washing.md
  1. You can specify one or more variables in the replacement string. Here, {p}, {f}, and {ext} are separate variables referring to the parent directory, filename, and extension respectively.

    f2 -r "{p}_{f}{ext}"
  2. When the renaming operation is carried out, F2 replaces each variable with the corresponding data from the file:

    • {p} is replaced with house-chores as it is the parent directory for each file.
    • {f} is replaced with the original filename of the file (cleaning, laundry, etc)
    • {ext} is replaced with the original extension of each file (.md)
    f2 -r "{p}_{f}{ext}"
    ┌─────────────────────────────────────────────────┐
    | ORIGINAL    | RENAMED                  | STATUS |
    | *********************************************** |
    | cleaning.md | house-chores_cleaning.md | ok     |
    | laundry.md  | house-chores_laundry.md  | ok     |
    | mowing.md   | house-chores_mowing.md   | ok     |
    | washing.md  | house-chores_washing.md  | ok     |
    └─────────────────────────────────────────────────┘
    
  3. Variables can be transformed in several ways. For example, you may uppercase the filename as shown below:

    f2 -r "{p}_{f.up}{ext}"
    ┌─────────────────────────────────────────────────┐
    | ORIGINAL    | RENAMED                  | STATUS |
    | *********************************************** |
    | cleaning.md | house-chores_CLEANING.md | ok     |
    | laundry.md  | house-chores_LAUNDRY.md  | ok     |
    | mowing.md   | house-chores_MOWING.md   | ok     |
    | washing.md  | house-chores_WASHING.md  | ok     |
    └─────────────────────────────────────────────────┘
    

    Such transformations (uppercase, lowercase, titlecase etc) are global to all variables provided by F2. However, some variables also sport their unique customisation options. For example, the {p} variable can be used for more than just the immediate parent directory.

    Assuming the absolute path for the house-chores directory is:

    /home/ayo/dev/demo/f2/house-chores
    

    You may retrieve each directory in the path by prefixing the {p} variable with a number as in {2p}, {3p} etc. Here, this will yield the following output:

    • {p} or {1p}: house-chores
    • {2p}: f2
    • {3p}: demo
    • {4p}: dev
    • and so on
    f2 -r "{3p.up}_{2p}_{p}_{f.up}{ext}"
    ┌─────────────────────────────────────────────────────────┐
    | ORIGINAL    | RENAMED                          | STATUS |
    | ******************************************************* |
    | cleaning.md | DEMO_f2_house-chores_CLEANING.md | ok     |
    | laundry.md  | DEMO_f2_house-chores_LAUNDRY.md  | ok     |
    | mowing.md   | DEMO_f2_house-chores_MOWING.md   | ok     |
    | washing.md  | DEMO_f2_house-chores_WASHING.md  | ok     |
    └─────────────────────────────────────────────────────────┘
    

Now that you know how variables work in F2, let's explore the different variables on offer.

1. Filename and path variables

These variables help you access the original file path for each file in the renaming operation.

  • {f}: the original filename (excluding the extension).
  • {p}: a directory in the file path. Can be prefixed with a number to move up to the desired level in the path.
  • {ext}: the file extension (including the .).

Note: since directories do not have extensions, {f} will always correspond to the full name of the directory and {ext} will always be an empty string regardless of the presence of a period in the name.

2. Date variables

The datetime attributes of a file can be used in its replacement string. F2 provides variables that enable you to access the file creation time, modification time, access time and more.

  • ctime: The time at which file metadata was changed.
  • btime: File birth time (Windows and macOS only).
  • atime: The last time the file was accessed or read.
  • mtime: The last time the contents of the file was modified.
  • now: The current time.

The above variables must be combined with a date token (see below)

Date tokens

Token Explanation Output
YYYY Year represented by a full four digits 1970 1971 ... 2029 2030
YY Year represented only by the last two digits 70 71 ... 29 30
MMMM Name of the month January February ... November December
MMM Abbreviated name of the month Jan Feb ... Nov Dec
MM Month as digits with leading zeros for single-digit months 01 02 ... 11 12
M Month as digits without leading zeros for single-digit months 1 2 ... 11 12
DDDD Name of the day of the week Monday Tuesday ... Saturday Sunday
DDD Abbreviated name of the day of the week Mon Tue ... Sat Sun
DD Day of the month as digit with leading zeros 01 02 ... 30 31
D Day of the month as digit without leading zeros 1 2 ... 30 31
H 24 Hours clock 01 02 ... 22 23
hh Hours with leading zeros for single-digit hours 01 02 ... 11 12
h Hours without leading zeros for single-digit hours 1 2 ... 11 12
mm Minutes with leading zeros for single-digit minutes 01 02 ... 58 59
m Minutes without leading zeros for single-digit minutes 1 2 ... 58 59
ss Seconds with leading zeros for single-digit seconds 01 02 ... 58 59
s Seconds without leading zeros for single-digit seconds 1 2 ... 58 59
A AM PM AM PM
a am pm am pm

Example

You can use date variables to organise files based on when they were last modified for example:

f2 -f '.*webp$' -r '{mtime.MMM}-{mtime.DD}-{mtime.YYYY}_image{%003d}{ext}'
┌─────────────────────────────────────────────────────────┐
| ORIGINAL           | RENAMED                   | STATUS |
| ******************************************************* |
| 34e7dcd7.webp      | Jun-18-2022_image001.webp | ok     |
| 7zwffegy91871.webp | Jun-03-2022_image002.webp | ok     |
| alan_p.webp        | May-29-2022_image003.webp | ok     |
| eiuz4tzc2le71.webp | Jun-03-2022_image004.webp | ok     |
| image-2-1.webp     | Apr-23-2022_image005.webp | ok     |
| qeila4tnvr971.webp | Jun-03-2022_image006.webp | ok     |
└─────────────────────────────────────────────────────────┘

3. Exif variables

The Exif attributes of an image file can also be used during a file renaming operation. F2 provides variables that allow you to access the most common Exif attributes such as ISO, image creation date, aperture, model, make, dimensions, focal length and more (see the full list below).

You can use each variable like this: {x.<var>} or {exif.<var>} as in {{exif.iso}} or {{x.make}}. If an Exif attribute is not present in the renamed file, the corresponding variable will be replaced with an empty string.

Note that exif attributes only work for image files such as JPEG, DNG, and most other RAW image formats (CR2, NEF, RAF, ARW, e.t.c.). HEIC/HEIF format is not supported at the moment.

Currently supported Exif variables:

  • iso: The ISO at which the image was captured.
  • w: The image width.
  • h: The image height.
  • model: The camera model (e.g. Canon EOS 5D Mark III).
  • make: The camera maker (e.g. Canon).
  • lens: The lens model.
  • et: The exposure time (e.g. 1/400) which is outputted as 1_400.
  • wh: The image dimensions (e.g 4032x3024).
  • fnum: The aperture (e.g. 1.6).
  • fl: The focal length of the lens (e.g 52).
  • soft: The software (e.g. Adobe Lightroom).
  • fl35: The 35mm equivalent focal length.
  • lat: The latitude.
  • lon: The longitude.
  • cdt: The image creation date (a.k.a. DateTimeOriginal). This must be combined with a date token (e.g {x.cdt.YYYY}).

Example

f2 -r '{x.model}-{x.fl}mm-ISO{x.iso}-{x.make}-{f}{ext}'
┌────────────────────────────────────────────────────────────────────────────────────┐
| ORIGINAL        | RENAMED                                                 | STATUS |
| ********************************************************************************** |
| bike.jpeg       | SM-G975F-4.32mm-ISO50-samsung-bike.jpeg                 | ok     |
| proraw.dng      | iPhone 12 Pro Max-5.1mm-ISO32-Apple-proraw.dng          | ok     |
| tractor-raw.cr2 | Canon EOS 5D Mark III-24mm-ISO200-Canon-tractor-raw.cr2 | ok     |
└────────────────────────────────────────────────────────────────────────────────────┘

ID3 variables

ID3 attributes from audio formats such as MP3, FLAC, OGG, M4A, ACC e.t.c can be accessed via the following ID3 variables:

  • title: The title of the track.
  • artist: The track artist.
  • album_artist: The album artist.
  • album: The album name.
  • format: The file format (e.g VORBIS, ID3v2.3).
  • type: The file type (e.g MP3, OGG, FLAC).
  • year: The release year.
  • track: The track number.
  • total_tracks: The total number of tracks in the album.
  • disc: The disc number.
  • total_discs: The total number of discs in the album.

If a specified ID3 attribute is not present in a file, the corresponding variable will be replaced with an empty string.

Example

Here's an example that uses ID3 attributes to organise the tracks in an album into following directory structure artist/album/title:

f2 -f '(\d+).*' -r '{id3.artist}/{id3.album}/${1}_{id3.title}{ext}'
┌───────────────────────────────────────────────────────────────────────────────────────────────┐
| ORIGINAL                      | RENAMED                                              | STATUS |
| ********************************************************************************************* |
| 01 - Jumpsuit.flac            | Twenty One Pilots/Trench/01_Jumpsuit.flac            | ok     |
| 02 - Levitate.flac            | Twenty One Pilots/Trench/02_Levitate.flac            | ok     |
| 03 - Morph.flac               | Twenty One Pilots/Trench/03_Morph.flac               | ok     |
| 04 - My Blood.flac            | Twenty One Pilots/Trench/04_My Blood.flac            | ok     |
| 05 - Chlorine.flac            | Twenty One Pilots/Trench/05_Chlorine.flac            | ok     |
| 06 - Smithereens.flac         | Twenty One Pilots/Trench/06_Smithereens.flac         | ok     |
| 07 - Neon Gravestones.flac    | Twenty One Pilots/Trench/07_Neon Gravestones.flac    | ok     |
| 08 - The Hype.flac            | Twenty One Pilots/Trench/08_The Hype.flac            | ok     |
| 09 - Nico and the Niners.flac | Twenty One Pilots/Trench/09_Nico and the Niners.flac | ok     |
| 10 - Cut My Lip.flac          | Twenty One Pilots/Trench/10_Cut My Lip.flac          | ok     |
| 11 - Bandito.flac             | Twenty One Pilots/Trench/11_Bandito.flac             | ok     |
| 12 - Pet Cheetah.flac         | Twenty One Pilots/Trench/12_Pet Cheetah.flac         | ok     |
| 13 - Legend.flac              | Twenty One Pilots/Trench/13_Legend.flac              | ok     |
| 14 - Leave the City.flac      | Twenty One Pilots/Trench/14_Leave the City.flac      | ok     |
└───────────────────────────────────────────────────────────────────────────────────────────────┘

5. Random string variable

The {r} variable is provided for the insertion of a random string in the new name. By default, it returns a random string of 10 letters but the output length and character set can be customised through the following syntax {{<number>r_<characters>}}. If the number is omitted, it defaults to 10.

For example:

  • {r}: Returns a random string of 10 letters.
  • {5r}: Returns a random string of 5 letters.
  • {15r_d}: This returns a random string composed of 15 digits. The _d is a shorthand for digits 0-9.
  • {8r_ld}: Returns a random string composed of letters and digits (_ld is shorthand for letters a-z and digits 0-9).
  • {r<abcdefgh>}: Returns a random string of 10 characters composed only of abcdefgh.
f2 -f 'go' -r '{15r_ld}' -e
+--------+---------------------+--------+
| INPUT  |       OUTPUT        | STATUS |
+--------+---------------------+--------+
| go.mod | yuye4fwb76pk0pa.mod | ok     |
| go.sum | 3qshovztgiwoszz.sum | ok     |
+--------+---------------------+--------+

Note that the random string you see in the preview is not going to match what is committed to the filesystem as it will be generated all over again when the operation is executed.

6. File hashes

F2 supports the use of file hashes in the replacement string using {hash.<function>} where <function> is md5, sha256, sha1, or sha512.

Example

f2 -f '^(1|2)\.mkv' -r '{hash.md5}{ext}'
┌──────────────────────────────────────────────────────────┐
| ORIGINAL | RENAMED                              | STATUS |
| ******************************************************** |
| 1.mkv    | d41d8cd98f00b204e9800998ecf8427e.mkv | ok     |
| 2.mkv    | ddd5752b5fe66fd98fb9dcdee48b4473.mkv | ok     |
└──────────────────────────────────────────────────────────┘

7. Exiftool variables

Besides the built-in variables above, F2 also integrates with exiftool, a popular program for reading and writing file metadata. This allows you to access almost 25,000 unique tags for a wide variety of file formats!

Before you can utilize exiftool variables, you need to have the program installed on your computer. The syntax for inserting an exiftool variable in the replacement string is {xt.<tag>} where <tag> is the desired tag name. To find out the available tag names for a given file, use the following command:

exiftool -j 1984-george-orwell.epub
[{
  "SourceFile": "/mnt/c/Users/gt/MEGA/books/Fiction/1984-george-orwell.epub",
  "ExifToolVersion": 11.88,
  "FileName": "1984-george-orwell.epub",
  "Directory": "/mnt/c/Users/gt/MEGA/books/Fiction",
  "FileSize": "285 kB",
  "FileModifyDate": "2020:03:20 18:32:42+01:00",
  "FileAccessDate": "2021:04:27 09:49:19+01:00",
  "FileInodeChangeDate": "2020:10:21 00:43:56+01:00",
  "FilePermissions": "rwxrwxrwx",
  "FileType": "EPUB",
  "FileTypeExtension": "epub",
  "MIMEType": "application/epub+zip",
  "MetaContent": "cover-image",
  "MetaName": "cover",
  "Type": "Text",
  "IdentifierId": "bookid",
  "Identifier": "1984GeorgeOrwell_201506",
  "Creator": "George Orwell",
  "Date": 1948,
  "Description": "The dystopian novel about the totalitarian world of three major governments that would emerge after world war two was lost by the Germans. <br /><br />Part of the ironic inversion of reality that the post war \"1984\" government would create is that of Emanuel Goldstein, he would be the symbol of the bad guy, even though his co-religionists in real life are the ones pulling the strings of the world governments behind the scenes. <br />",
  "Language": "en",
  "Subject": [1984,"George Orwell","Dystopian","Totalitarianism"],
  "Title": "1984 George Orwell",
  "ManifestItemHref": "stylesheet.css",
  "ManifestItemId": "css",
  "ManifestItemMedia-type": "text/css",
  "SpineToc": "ncx",
  "SpineItemrefIdref": "leaf0000",
  "SpineItemrefLinear": "yes",
  "GuideReferenceHref": "leaf0000.html",
  "GuideReferenceTitle": "Title Page",
  "GuideReferenceType": "title-page"
}]

The tag names in this example are: SourceFile, FileName, Creator, Title, e.t.c.

Example

Here's an example that utilises some of these tags in a renaming operation for a set of EPUB files:

f2 -r '{xt.Title} - {xt.Creator}{ext}'
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
| ORIGINAL                                  | RENAMED                                            | STATUS |
| ******************************************************************************************************* |
| 1984-george-orwell.epub                   | 1984 George Orwell - George Orwell.epub            | ok     |
| bunyan-pilgrim-s-progress.epub            | The Pilgrim's Progress - John Bunyan.epub          | ok     |
| Dracula.epub                              | Dracula - Bram Stoker.epub                         | ok     |
| Emma - Austen Jane.epub                   | Emma - Jane Austen.epub                            | ok     |
| Friend Island.epub                        | Friend Island - Francis Stevens.epub               | ok     |
| hill-think-and-grow-rich.epub             | Think and Grow Rich - Napoleon Hill.epub           | ok     |
| Leviathan by Thomas Hobbes.epub           | Leviathan - Thomas Hobbes.epub                     | ok     |
| The Lost World by Arthur Conan Doyle.epub | The Lost World - Arthur Conan Doyle.epub           | ok     |
| The Mysteries of Udolpho.epub             | The Mysteries of Udolpho - Ann Ward Radcliffe.epub | ok     |
| The Night Land.epub                       | The Night Land - William Hope Hodgson.epub         | ok     |
| The Parasite.epub                         | The Parasite: A Story - Arthur Conan Doyle.epub    | ok     |
| The Raven.epub                            | The Raven - Edgar Allan Poe.epub                   | ok     |
| The Trial.epub                            | The Trial - Franz Kafka.epub                       | ok     |
| the-shunned-house.epub                    | The Shunned House - H. P. Lovecraft.epub           | ok     |
| Ulysses by James Joyce.epub               | Ulysses - James Joyce.epub                         | ok     |
| War and Peace by Graf Leo Tolstoy.epub    | War and Peace - Graf Leo Tolstoy.epub              | ok     |
└─────────────────────────────────────────────────────────────────────────────────────────────────────────┘

As you can see, the naming scheme is now consistent for all the files: <Title> - <Author>.epub. Please note that if the tag value contains a forward or backward slash, it will be replaced with an underscore as slashes have a special meaning when used in the replacement string. So if the tag value is application/epub.zip, it will be outputted as application_epub+zip.

8. String transformation

F2 provides options for transforming file names in a variety of ways. For example, you can convert characters in a file name to uppercase or lowercase, or you can extract a date and transform it however you wish. These transformations can be applied to the entire filename, a subset of the filename, or a capture variable.

Case transformation

The following options are provided for changing the case of some or all characters in a file:

  • {.up} for UPPERCASE.
  • {.lw} for lowercase.
  • {.ti} for Title Case.

Example

  1. Make the entire filename lowercase:

    f2 -r '{.lw}'
    ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
    | ORIGINAL                                  | RENAMED                                   | STATUS |
    | ********************************************************************************************** |
    | The Lost World by Arthur Conan Doyle.epub | the lost world by arthur conan doyle.epub | ok     |
    | Ulysses by James Joyce.epub               | ulysses by james joyce.epub               | ok     |
    | War and Peace by Graf Leo Tolstoy.epub    | war and peace by graf leo tolstoy.epub    | ok     |
    └────────────────────────────────────────────────────────────────────────────────────────────────┘
    
  2. Capture the author names and make them uppercase

    f2 -f '(.*) by (.*)' -r '$1 - {<$2>.up}' -e
    ┌───────────────────────────────────────────────────────────────────────────────────────────────┐
    | ORIGINAL                                  | RENAMED                                  | STATUS |
    | ********************************************************************************************* |
    | The Lost World by Arthur Conan Doyle.epub | The Lost World - ARTHUR CONAN DOYLE.epub | ok     |
    | Ulysses by James Joyce.epub               | Ulysses - JAMES JOYCE.epub               | ok     |
    | War and Peace by Graf Leo Tolstoy.epub    | War and Peace - GRAF LEO TOLSTOY.epub    | ok     |
    └───────────────────────────────────────────────────────────────────────────────────────────────┘
    
  3. Replace hyphen with a space and transform entire filename to title case (except the extension)

f2 -f '-' -r ' ' -r '{.ti}' -e
┌────────────────────────────────────────────────────────────────────────┐
| ORIGINAL                      | RENAMED                       | STATUS |
| ********************************************************************** |
| 1984-george-orwell.epub       | 1984 George Orwell.epub       | ok     |
| hill-think-and-grow-rich.epub | Hill Think And Grow Rich.epub | ok     |
| the-shunned-house.epub        | The Shunned House.epub        | ok     |
└────────────────────────────────────────────────────────────────────────┘

Cleaning up filenames

The following set of transformations can help you clean up your file names when migrating to a different operating system due to the differences in characters allowed in the names.

Here are the available options:

  • {.win}: Remove characters not allowed in Windows' file names (<, >, ", :, \, /, |, ? and *).
  • {.mac}: Remove characters not allowed in macOS file names (:).
  • {.di}: Replace diacritics in file names so that très bien.jpg becomes tres bien.jpg.

Example

  1. Strip file name of Windows forbidden characters and replace multiple spaces with a single one:

    f2 -f '.*' -r '{.win}' -f '[ ]{2,}' -r ' '
    ┌──────────────────────────────────────────────────────────────────────────────────────────────────────┐
    | **************************************************************************************************** |
    | ORIGINAL                                          | RENAMED                                 | STATUS |
    | This file <> contains ::: ?\ forbidden characters | This file contains forbidden characters | ok     |
    └──────────────────────────────────────────────────────────────────────────────────────────────────────┘
    
  2. Remove diacritics from file names:

    f2 -f 'žůžo' -r '{.di}'
    ┌──────────────────────────────┐
    | ORIGINAL | RENAMED  | STATUS |
    | **************************** |
    | žůžo.txt | zuzo.txt | ok     |
    └──────────────────────────────┘
    

Parsing arbitrary text as date

You can try to parse arbitrary text as a date by using the {.dt.<token>} variable where <token> corresponds to a date token. This is useful when a filename contains a date and you'd like to transform it in some manner. F2 will attempt to parse the string as a date and it will produce the appropriate value as according to the <token> if the date is valid. If the string cannot be converted to a date, it will be used in the new filename as is.

Example

f2 -f "Screenshot from (.*)\.png" -r '{<$1>.dt.YYYY}/{<$1>.dt.MMMM}/{f}{ext}'
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
| ORIGINAL                                | RENAMED                                                                         | STATUS |
| ********************************************************************************************************************************** |
| Screenshot from 2022-04-12 14:37:35.png | 2022/April/Screenshot from 2022-04-12 14:37:35.png                              | ok     |
| Screenshot from 2022-04-12 15-58-55.png | 2022-04-12 15-58-55/2022-04-12 15-58-55/Screenshot from 2022-04-12 15-58-55.png | ok     |
| Screenshot from 2022-06-03 11:29:16.png | 2022/June/Screenshot from 2022-06-03 11:29:16.png                               | ok     |
| Screenshot from 2022-09-26 21:19:15.png | 2022/September/Screenshot from 2022-09-26 21:19:15.png                          | ok     |
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Notice how the date in the Screenshot from 2022-04-12 15-58-55.png file wasn't able to be parsed due to the use of hypens instead of : in its time component. In such cases, you could replace the last two hypens on that specific file first before proceeding:

f2 -f "-" -r ':' -l '-2' Screenshot\ from\ 2022-04-12\ 15-58-55.png
┌────────────────────────────────────────────────────────────────────────────────────────────┐
| ORIGINAL                                | RENAMED                                 | STATUS |
| ****************************************************************************************** |
| Screenshot from 2022-04-12 15-58-55.png | Screenshot from 2022-04-12 15:58:55.png | ok     |
└────────────────────────────────────────────────────────────────────────────────────────────┘