arename(1)
β¨ NAME β¨
hi bestie π welcome to arename, aka arename(1) β the tool that automatically renames audio files by tagging information. yes, by tagging information. she reads the tags, she makes the names make sense. iconic behaviour, honestly. π
π SYNOPSIS π
arename [OPTION(s)] FILE(s)...
π OPTIONS AND ARGUMENTS π
okay so here's the whole menu, no skipping, we read every single one πΈ
--ambiguous-use-firstβ turns on theambiguoususefirstoption. more on that down below, bestie.--compare-versionsβ prints the version of thearenamescript and the version of the Perl module that holds most of the code. these two are supposed to match. if they don't match, that's a sign your installation might be broken. π«--copy(short option:-c) β copies files instead of renaming (moving) them. super handy when you're copying tracks from your audio archive over to a portable device, for example.--debugβ turns on debugging output. lowkey this literally setsverbosityto10000. and bestie, that output option is going to be so noisy π you probably want something chiller, like--verbosity 20.--disable-hooks(short option:-H) β don't use hooks of any sort. neither global ones nor local ones.--disable-profiles(short option:-N) β don't use configuration profiles (see below). this overwrites theuseprofilessetting.--dryrun(short option:-d) β go into dryrun mode. this means no action gets taken at all.arenamejust prints what it would do if you'd called it without-d. perfect for a vibe check before you commit β¨--enable-hooksβ explicitly enable hooks. saying the quiet part loud, we love that.--force(short option:-f) β overwrite files if needed. use with intention, bestie π--help(short option:-h) β display a short help text.--list-cfg(short option:-L) β list the current configuration in the actual configuration format.--list-file-typesβ lists every file typearenamecurrently supports right now, one type per line.--list-exts-for-type <type[,type[,...]]>β lists every file name extension recognised for the type<type>, one extension per line. if you hand it a comma-separated list of types, it lists the extensions for all of the listed types.--list-profiles(short option:-S) β prints a list of profile names defined in the active configuration. (this is mainly used by the zsh completion for the--profileoption, iykyk.)--read-local(short option:-l) β read a local config file (./.arename.local). overwrites theuselocalrcconfiguration setting.--stdin(short option:-s) β read filenames from stdin after processing the files given on the command line. it reads one file name per line, which means file names containing newlines are not supported. π«Ά--version(short option:-V) β display version information.--verbosity <integer-value>β sets theverbositysetting tointeger-value.--suppress-skips(short option:-Q) β when a file gets skipped because its name wouldn't change, this option makesarenamesuppress any output about it. this sets thesuppress_skipsoption.
heads up bestie: if the verbosity setting is at a high enough level, you may still get messages about the file being processed in the first place. π«
--rc <file>β read file instead of~/.arenamerc.--post-rc <file>β read file after~/.arenamercand before./.arename.local.--prefix <prefix>(short option:-p) β define a prefix for destination files.--profile <profile(s),...>(short option:-P) β define a list of one or more profiles to use forcibly, no matter whether they'd be activated normally or not. no cap, you're the one choosing.--compilation-template <template>(short option:-T) β define a template that gets used for files that contain a compilation tag.--template <template>(short option:-t) β define a generic template, for all files that do not contain a compilation tag.--userset <variable=value>(short option:-u) β set a user defined variable to a given value (see "User defined variables" below).FILE(s)...β input files that are subject for renaming.
okay a word about option name stability, and this one actually matters so listen up π
With arename version 3.0 we are now using Getopt::Long for parsing command line options. That change happened because the meaningful single letter options were used up. Every option is available via a --long-option. That interface will stay stable. If changes to the --long-option interface do happen, that'll happen with an appropriate deprecation phase, so users can adjust. So if you want to use arename in scripts, those are the options you should use. There are currently no plans of removing or changing any further short options, but there are no guarantees. If it is indeed better to change a short option, we will do so. π
A list of options that changed from arename 3.x to 4.0 can be found in the project's CHANGES file, and general advice about incompatible changes from major version to major version is documented in the UPGRADING file. π
π« Deprecated Command Line Options
these ones are deprecated and will be removed in a later version of arename. don't get attached, bestie π
--quietβ this option is a short hand for--verbosity 10.--uber-quietβ this option is a short hand for--verbosity 5.--verboseβ this is a short hand for--verbosity 20.
π¦ DESCRIPTION π¦
arename is a tool that is able to rename audio files by looking at a file's tagging information. It uses this information to assemble a consistent destination file name. The user can define the format of the destination filename by the use of template strings. π
Templates can be defined in the "Configuration files", by the template and comp_template settings (See "SETTINGS" below).
By default, arename will refuse to overwrite destination files if the file in question already exists. You can force overwriting by supplying the --force option.
In order to see what would happen instead of actually modifying files, you can use the --dryrun option. This way you can avoid problems that would occur if the situation (e.g. the information in the files or your configuration) is not exactly as you expected it. main character energy: check first, slay second π
π Supported file formats
Since version 4.0, arename supports a lot more file formats than it used to (version 3.0 only supported .mp3, .ogg and .flac files). Thanks to Audio::Scan, we now support a much wider range of file types, of which most may exist using different file name extensions (e.g. *.ogg and *.oga are both of the type ogg). obsessed with the range honestly β¨
You may use the --list-file-types' and --list-ext-for-type' options to find out which file type is mapped to which file name extensions.
If you would like support for another file type in arename, you will have to persuade the Audio::Scan developers to extend their module with said feature. Adding support for it in arename after that should be trivial. π«Ά
To give you an idea, arename (in connection with Audio::Scan 0.85) lets you rename mp3, mp4, aac, ogg, flac, asf, musepack, monkey audio, wav (this type also supports aiff) and wavpack files.
ποΈ Inputting a lot of files
arename can be used to keep the file names of whole audio archives in sync. However, that means that you will have to tell the script the location of many files, thousands maybe. π³
In order to do that you will face the problem, that on most UNIX-like systems, the length of the argument list for external programs is limited (recent Linux versions, as an exception, do not have that limitation anymore).
So, even if your shell can do recursive globbing like ksh or zsh, this will most likely get you into trouble (for more than just a few files):
% arename -d **/*.mp3
There are several ways to overcome that limitation, of course.
The first solution is to use find in connection with arename's -s option:
% find . -name "*.mp3" -print | arename -d -s
This will break for file names that contain newlines, because --stdin will read one file name per line from the standard input stream. π«
Another way of using find to deal with this problem is to use find's -exec option:
% find . -name "*.mp3" -exec arename -d '{}' '+'
This will work for every possible file name. No matter if it has spaces or newlines in it. The + at the end of the call causes find to call the external program (arename in this case) with as many arguments as possible, without exceeding the limit. This requires a POSIXly correct find. GNU find for instance, did not support the + way for a long time. If you are stuck with an old version, you can exchange the + with a ; (note, that a semicolon must be quoted in any case), or use the xargs tool instead.
A last solution for zsh users would be zargs (which requires autoload zargs in your zsh configuration):
% zargs -- **/*.mp3 -- arename -d
πΈ GENERAL USAGE πΈ
When you are first confronted with arename and you try to get started with the documentation you might argue, that a 1000+ lines manual, that is not filled with too many examples is hardly starter-friendly. and like... fair π
Therefore, this section was introduced to give you the bare minimum of information in order to use the program without going through too much fuzz.
If you are really afraid of documentation, you could of course just read the output of the --help option and see which options to provide in order to get what you want. Then again, you will soon be pissed by the weird default values arename uses. π
You will probably want other templates. After all, the ability to have these expanded strings is one of the points to use arename in the first place. They are described in the TEMPLATE section; and reading that section is the minimum effort you will want to go through.
After that, you can open the file ~/.arenamerc in your favourite text editor and resemble the following text (and presumably change the few values in there to your liking):
# now you certainly want your own templates, so define them here
# one for your normal files
template &artist - &album - &tracknumber. &tracktitle
# and another one for files that orignate from compilations
comp_template va - &album - &tracknumber. &artist - &tracktitle
If you want more automation or more customization, you will not get around reading the manual below. If you need to solve special problems, the "HOOKS" part even further below is for you. π
πΈ ENVIRONMENT VARIABLES πΈ
bestie these are the lil knobs the environment can flip before arename even wakes up, ok? π«Ά
ARENAME_LOAD_QUIETβ set this to1and arename will straight up not say a word while starting up. no startup messages at all β not while it's reading the configuration or hook files, and not even the lil messages about whether it's in copy mode or on a dry-run or anything like that. π
but listen β if warnings or errors pop up while loading the configuration, those messages still get emitted, of course. quiet doesn't mean it's gonna hide problems from you, bestie. π
any other value but 1 β and that literally includes ARENAME_LOAD_QUIET just not being in the environment at all β means arename starts up in its normal chatty manner. periodt.
ARENAME_SUPPRESS_COLOURSβ set this to1(and only1β arename will ignore literally any other setting, no cap) and arename turns off all its output colourations. as of version4.0, arename usesTerm::ANSIColorto produce output, which is what gives it those terminal colours. so yeah, that's the vibe you're killing here. π
π¦ FILES π¦
arename's whole personality can be altered by a bunch of files it reads when it's starting up. iconic behaviour honestly.
normal configuration tasks? those go in the (how convenient) "Configuration files", described below. β¨
if you need more control, or you're trying to solve some special problem you're having, you can do that by supplying Perl code in "Hook definition files". that's the big-girl stuff. π
arename can be configured to read configuration files as well as hook definition files from the current working directory. this feature is disabled by default, because β and I cannot stress this enough β they can be a security issue on multiuser systems. so like, turn it on knowing that, okay? π
there are no such things as system wide configuration files in arename. none. it's not that kind of program.
for all setup files arename tries to find (except for the local ones), four different locations are tried. here's the tea:
- if the
$XDG_CONFIG_HOME/arenamedirectory exists, all files are expected to be there. - if that directory does not exist,
~/etc/arename/is tried. - and if that is not there,
~/.arenameis tried instead. - if those directories could not be found either, arename will try to find the file it's looking for directly in the user's home directory.
the default for $XDG_CONFIG_HOME is ~/.config.
the first setup directory we find always wins. arename does not consider more than one setup directory. it's loyal like that. π
if, for example, ~/etc/arename/ exists and we are looking for the normal configuration file (see below), but ~/etc/arename/rc could not be found, we do not try to find it in ~/.arename/ or the user's home directory. nope. that ship has sailed. π
β¨ Configuration files β¨
arename uses up to three configuration files. as for most programs, the script will try to read a configuration file that is located in the user's home directory. on top of that, it will try to load local configuration files, if it finds appropriately named files in the current directory (and the uselocalrc feature is enabled):
$XDG_CONFIG_HOME/arename/rc~/etc/arename/rc~/.arename/rc~/.arenamercβ the per-user normal configuration file. π./.arename.localβ the per-directory local configuration file (only read ifuselocalrcis set or the--read-localoption is given on the command line).
the per-user normal configuration file can be substituted by another file, if specified via the --rc option.
last but not least, you can specify an intermediate configuration file, that is read in between the normal and the per-directory file, via the --post-rc option. fancy, right? π
π File format π
the format of the aforementioned files is pretty simple, bestie. it is parsed line by line. empty lines, lines only containing whitespace, and lines whose first non whitespace character is a hash character (#) are all ignored. so go ahead and leave yourself lil notes.
there are two different types of settings: boolean and scalar settings.
booleans can be set like this:
<setting> [true|false]
if the value is omitted, true is assumed. true and false are recognized case insensitively, and a value of 1 is synonymous to true, as is 0 to false.
scalar settings are done in a very similar way:
<setting> <value>
if the value is omitted, string values will be set to an empty string and numeric values will be set to zero.
in both cases, setting and value are separated by one or more whitespace characters. the value will be the rest of the line (all of it, including trailing whitespace). yes, all of it. π«Ά
if the value part starts with a backslash, that backslash is left out of the value. that makes it possible to define templates with leading whitespace. sneaky but useful. π
if a line contains only a string within square brackets, that string is the start of a section. section names are matches for starts of file names. that means, the settings following such a section definition will only be applied for input file names that start with the same string as the section name. where file name means the string handed over to arename. the string ~/ at the beginning of a section name is expanded to the user's home directory.
you may start as many sections as you would like. go off. π
a section named /foo/bar/ supersedes a section named /foo/ for a file named /foo/bar/baz.ogg. so, the longest match wins. that's the rule, no exceptions.
another possible configuration file entry is a user variable, which is defined via the set command. these settings are very different from the normal settings, so they're defined in a different way. that way is described in the "User defined variables" subsection below.
last but not least, you may define so called profiles, see below. π
π Configuration profiles π
profiles are a very flexible and context sensitive way of using multiple configuration files at once. with profiles, local configuration files (and local hook definition files) can be substituted in a secure way β even on multi-user systems. chef's kiss. π
reading local files (configs and hook-files) is still supported for backwards compatibility (see the uselocalrc and uselocalhooks options). however, you are strongly encouraged to use profiles whenever you can. like, please bestie, do it for me.
as normal configuration files and global hook-files, profile-related files are searched in one of the setup directories described above. they're using the following naming conventions:
$XDG_CONFIG_HOME/arename/profile.PROFILENAME~/etc/arename/profile.PROFILENAME~/.arename/profile.PROFILENAME~/.arename.PROFILENAMEβ profile related configuration files; read ifPROFILENAMEis active.
they are read after an intermediate config file defined by --post-rc and a local config file (if enabled).
$XDG_CONFIG_HOME/arename/profile.PROFILENAME.hooks~/etc/arename/profile.PROFILENAME.hooks~/.arename/profile.PROFILENAME.hooks~/.arename.PROFILENAME.hooksβ profile related "Hook definition files" (see below for details); read ifPROFILENAMEis active.
these files are read between global and local hook-definition files.
in order to define profiles, you need to use the profile keyword:
profile <name> <pattern>
where name is a string that is used in the place of PROFILENAME in the file location lists above. this name may contain of the following character range: a-zA-Z0-9_-
pattern is part of a Perl regex pattern (see the perlreref and perlretut manpages). the pattern will be anchored at the beginning and is open at the end, somewhat like this pseudocode:
if ($working_directory =~ m/^PATTERN/) { use_this_profile(); }
example:
profile music /mnt/audio/music/
will cause the profile music to be active when the working directory is /mnt/audio/music/ or below. so, do not be afraid. you can use profiles without understanding regular expressions. fr fr. π§
like many other values in arename's configuration, a leading backslash of a pattern will be ignored to allow patterns that start in white spaces. furthermore, if a pattern starts in ~/, that string is replaced by the user's home directory.
you may add as many patterns to a profile name as you want:
profile music /mnt/audio/music/
profile music /mnt/extern/audio/music/
the above activates the music profile in /mnt/audio/music/ and /mnt/extern/audio/music/, for example. slay. β¨
more than one profile can be activated at the same time. if that is true, the according configuration files are read in lexical order. alphabetical besties, one after the other.
π Sections versus Profiles π
since arename provides two context sensitive configuration facilities, you might ask yourself when to use which, when you are confronted with both for the first time. totally valid question, bestie.
first of all, profiles are more powerful. they may even introduce new hooks for arename to use. but that is not the conceptual difference between the two. okay so here's the actual vibe:
sections are sets of configuration settings that are considered for each and every input file, and they are only enabled for input files whose name matches the section name.
profiles on the other hand are sets of configuration and hook-definition files, whose inclusion in the current arename run is decided at the beginning of the program's execution (not for every input file) β namely, if the name of the current working directory matches one of the profile's patterns.
that means: if you need to introduce slight configuration changes based on an input file's name, you want to use a section.
if you need to make broader configuration changes, considering the name of the current working directory, profiles are the way to go. π
of course, profile configuration files may introduce new sections, too. layers on layers, iconic. π§
π Configuration file example π
# switch on verbosity
verbosity 20
# canonicalize file names before working with them
canonicalize
# the author is crazy! use a sane template by default. :-)
template &artist - &album (&year) - &tracknumber. &tracktitle
# activate the 'music' profile below /mnt/audio/music/.
profile music /mnt/audio/music/
# force files from /foo/bar/ to stay below that directory
[/foo/bar/]
prefix /foo/bar
π Hook definition files π
$XDG_CONFIG_HOME/arename/hooks~/etc/arename/hooks~/.arename/hooks~/.arename.hooksβ defines global hooks, that are in effect in every directory if theusehooksoption is set totrue. π./.arename.hooks.localβ this allows you to define special hooks, that will only be applied for processes that run in the directory the local file is found (and if theuselocalhooksoption is set totrue). π
for details about hooks in arename, see "HOOKS" below. it's giving main character energy, you're gonna wanna read it. π
SETTINGS
Okay bestie, these are the settings you can drop into any of the configuration files. All of them. Every single one. π
Little heads-up though: not all of them work inside sections. The ones that do work in sections are: all default_* options, force, prefix, sepreplace, tnpad, comp_template and template. That's the guest list, everyone else stays outside. π
ambiguoususefirstβ so some tag types let you set the same tag multiple times. Rude, honestly. The scanning backends from beforearename4.0 didn't support tags like that at all.- Set it to
false(the default) andarenamejust throws its hands up and gives up the moment it runs into one of these tags. π - Set it to
trueandarenamesimply uses the first value it bumps into. Easy. β¨ - Want max control over how ambiguous-value tags get handled? Use the
ambiguoustaghook, that's your girl. (default:false)
- Set it to
canonicalizeβ if you set this, a given file name gets transformed into its cleaned-up absolute path. Lowkey useful if you're using sections in your config. If you're not using sections, all this does is cost you performance, soβ¦ skip it. (default value:false)checkprofilercβ if set,arenamechecks whether a config file exists for a profile the moment it reads a profile definition in the setup, and only counts that profile if it found the matching config file. Profiles with no config file will trigger a warning when this is on β and ifwarningsautodryrunis set, that warning can flipdryrunon. Careful. π- If it's unset, profiles without a config file won't cause warnings. You'll still see messages about missing config files whenever a profile without a config file is active. (default:
true)
- If it's unset, profiles without a config file won't cause warnings. You'll still see messages about missing config files whenever a profile without a config file is active. (default:
checktemplatesinitiallyβ if set,arenameinspects everytemplateandcomp_templatesetting for possible problems. Unsetting this probably only makes sense if you're doing template wizardry inside hooks and you 100% know what you're doing. Normal users, stay on the default, trust. (default:on)comp_templateβ defines the template used for files that carry a compilation tag (think 'various artist' CDs πΏ). This setting can still get overwritten by the--compilation-templatecommand line option. (default value:va/&album/&tracknumber - &artist - &tracktitle)default_*β that's:default_artist,default_album,default_compilation,default_genre,default_tracknumber,default_tracktitle,default_year- Each one defines a default value for that tag, used on files that are missing that info. (default value:
undefined)
hookerrfatalβ if this is set tofalse,arenamekeeps running even if reading, parsing or compiling a hooks file straight up failed. (default value:false)prefixβ defines a prefix for destination files. Set it to/foo/barand your destination files end up named/foo/bar/Expanded Template.ogg. Cute, right?- This setting can still be overwritten by the
--profilecommand line option. (default value:.)
- This setting can still be overwritten by the
sepreplaceβ tag info strings can contain slashes, which is a pretty bad idea on most file systems, no cap. So you get to define a string that replaces those slashes with whatever value you set here. (default value:_)suppress_skipsβ just like the--suppress-skipscommand line option, this kills the messages for filesarenameskips because the file name wouldn't change anyway. Silence is golden. πtemplateβ defines the template used for files that don't provide a compilation tag (or where the compilation tag and the artist tag are exactly the same). This setting can be overwritten by the--compilation-templatecommand line option. (default value:&artist[1]/&artist/&album/&tracknumber - &tracktitle)template_aliasesβ if this option is set,arenamelets you use abbreviated tag names intemplateandcomp_template. Peep "Available expression identifiers" below for the details. (default value:off)tnpadβ this defines the width that the track number field gets padded to with zeros on the left. Set it to zero and padding is disabled, periodt. (default value:2)usehooksβ if set totrue, use hooks defined in~/.arename.hooks. (default value:true)uselocalhooksβ if set totrue, use hooks defined in./.arename.hooks.local. (default value:false)uselocalrcβ if set totrue, read a local configuration file (./.arename.local), if it exists. (default value:false)useprofilesβ if set totrue, configuration profiles get used. Iffalse, they do not. (default value:true)usetypeasextensionβ one file type may be used for different file name extensions. For example, files matching*.oggand*.ogaboth get handled as typeogginAudio::Scan(the information gathering backendarenamehas been using since version 4.0).- When this option is
true, a file matching*.ogagets renamed using.oggas the extension, because its type isogg. Otherwise, the original extension is left untouched. (default:true)
- When this option is
verbosityβ integer option that sets how chattyarename's output is. Default value is10. The--verbosityoption can override this setting.warningsautodryrunβ switches on thedryrunoption (if it's not already on) the second the configuration file parser hits non-fatal warnings. This option exists specifically to avoid destructive behaviour from incorrect lines in any of the configuration files. Protect yourself. π«Ά (default value:true)
Deprecated Settings
These four are giving legacy, bestie. They do literally nothing and they're getting yeeted in a later version. All four of them. Use an appropriate verbosity setting instead. π
verboseβ this setting has no effect and will be removed in a later version. Use an appropriateverbositysetting instead.quietβ this setting has no effect and will be removed in a later version. Use an appropriateverbositysetting instead.quiet_skipβ this setting has no effect and will be removed in a later version. Use an appropriateverbositysetting instead.debugβ this setting has no effect and will be removed in a later version. Use an appropriateverbositysetting instead.
User defined variables
You can use the set command in arenamerc files. This way, the user gets to define their own variables. πΈ The namespace here is separate from arename's normal settings β meaning you cannot, for example, overwrite the internal template variable with this command. The vibes stay in their own lane. β¨
The syntax is super simple (and different from normal settings on purpose!):
set varname = value
There may be an arbitrary amount of whitespace around the equal sign (including no whitespace at all β we're flexible like that). If you want a value that starts with a whitespace character, you can start the value with a backslash character. Just like with the normal settings, a leading backslash is always ignored. π
You can also set user defined variables straight from the command line with the --userset option:
% arename --userset variable0=value
% arename -u variable0=value
User defined variables are useful for making hooks configurable (peep "HOOKS" below π). Starting with version 4 of arename, user defined variables can also be defined within sections, which (just like a normal option) makes them apply only if that section is used for a given file. Section-scoped, iconic behaviour honestly. π
β¨ TEMPLATE FORMAT β¨
okay bestie, so arename's templates are genuinely not that hard to get your head around, but they are powerful, like, lowkey iconic amounts of powerful. π
At the absolute simplest, a template is just a fixed character string. But likeβ¦ that would be kind of useless bestie, because then every single file you'd ever want to rename would get the exact same name π so that's why arename can expand certain expressions using info it gathered from the file's tagging info. It's giving glow-up for filenames fr fr.
An expression basically looks like one of these forms:
&identifierβ this is thetrivialexpression. It expands to the info stored in the corresponding tag. If that tag isn't available, the expansion of the template string fails. periodt, no tag no vibe. π&identifier[length]β thesizedexpression. The length modifier in the square brackets sets the maximum length the expression should expand to. So if a file's artist turns out to be 'Frank Zappa', then using&artist[1]expands to 'F'. cute little sneak peek π&{identifier:default-template}β this is the first complex expression, calledcomplex-default. When the tag corresponding toidentifieris available, this expands exactly like the trivial expression would. But if it's not available, the expansion doesn't fail β instead thedefault-templatestring gets expanded. a backup plan, we love her π«Ά&{identifier?set-template!unset-template}β this one's calledcomplex-set-unset. Again, what gets used during template expansion depends on whether the tag corresponding toidentifieris set or not. If it's set, theset-templatestring is expanded; if it's unset, theunset-templatestring is used.
And guess what, both of the simple expansions can be used with braces too, just like the complex ones:
&{identifier}β this is equal to&identifier.&{identifier[length]}β and this is equal to&identifier[length].
Backslashes are special in template strings bestie, because they quote characters that have special meaning β for example, to get an ampersand character you need to use "\&". To get an actual backslash in the resulting string, you need a backslash quoted by a backslash. And a backslash on non-special characters is silently dropped. sneaky little guy π
π¦ Nesting expressions π¦
In complex expressions, the strings called default-template, set-template and unset-template are subject to regular template expansion. So expressions like this are possible:
"&{album?&album/!}"
If album were set, it'd expand to its value followed by a slash; otherwise it'd expand to nothing. Using this, dealing with album-less tracks is genuinely easy:
"&artist/&{album?&album/&tracknumber. !-no-album-/}&tracktitle"
That effectively uses this template if album is set:
"&artist/&album/&tracknumber. &tracktitle"
But if it's not set, it uses this instead:
"&artist/-no-album-/&tracktitle"
Caution has to be taken if certain characters are to be used within conditional template expressions. For example, to use a closing curly bracket in either of them, it needs to be quoted using a backslash character.
Similarly, if an exclamation mark is to be used in a set-template, it needs to be quoted by a backslash so it doesn't get interpreted as the end of the set-template string. noted, bestie, write that down π
π Available expression identifiers π
The data that gets expanded is derived from tagging information in the audio files. There are two kinds of information available. One is the purely informational tag (like a track's artist) and the other further describes the format of the audio file (like the file's bitrate).
If you're defining a whole lot of templates on the command line, you might find these identifiers take quite a while to type. If the template_aliases option is set, you may use shorter alias names instead of the real identifier. Available aliases are listed with their corresponding identifier below. π
This is a list of all informational identifiers available for all file-types:
albumβ the album the currently processed track is part of. (alias:al)artistβ the artist for the current track. (alias:ar)compilationβ compilation tags are not very stable across different file types. Usually this is set to a string like"Various Artists"for tracks that are part of some sort of compilation album (like motion picture sound-tracks). (alias:cmp)genreβ the genre or content type of the audio file. (alias:gn)tracknumberβ the number of the position of the track on the disc. Obviously. However, this can be in the form of'12'or'12/23'. In the second form, only the part left of the slash is used. The tracknumber is a little special, as you can define to what width it should be padded with zeros on the left (see thetnpadsetting in "SETTINGS"). (alias:tn)tracktitleβ the title of the currently processed track. (alias:tt)yearβ chronological information about the track (usually the year a song was written or the year the album a track is part of was released). (alias:yr)
Here's a list of file-format information tags available for all file-types:
bitrateβ the bitrate the file was recorded/encoded with. (alias:br)channelsβ the number of channels available in the file (for example, this is2for stereo files). (alias:ch)length_msβ the length of the track in milli-seconds. (alias:ln)samplerateβ the samplerate the file was recorded/encoded with. (alias:sr)
For all file-types, the following tags are generated from the ones listed above (for convenience):
kbitrateβ kilobits per second (bitrate / 1000). (alias:kbr)ksamplerateβ kilosamples per second (samplerate / 1000). (alias:ksr)length_secβ the length of the track in seconds. (alias:ls)
Some tags are only available for certain file-types. They're always called type_*. File-type specific identifiers do not have alias names. Here's a list of those tags:
flac_wordsizeβ the word-size used in a flac file.24if samples are 24 bits wide.mp3_id3_versionβ the version of the id3 tag used in mp3 files (e.g."ID3v2.3.0").wav_id3_versionβ the same asmp3_id3_version, but for wave files.
π EXIT STATUS π
arename returns zero if everything went fine; non-zero on fatal problems. This may change in future versions. so like, don't build your whole personality around it bestie π
π₯ HOOKS π₯
Before we start, a word of warning: Hooks can solve a lot of problems. That amount of flexibility comes at its price. All data passed to hook functions are references to the actual data in the script (except for the namespace argument, which is a copy). If you write hooks carelessly, arename will get back at you!
HOOKS ARE A BIG HAMMER, THAT CAN CRUSH PROBLEMS AS WELL AS LIMBS!
You have been warned! π«£
π Discussion π
The reason for implementing hooks was to have a simple way of post processing tags, filenames etc. without having to invent your own magic in the configuration files, when Perl has regular expressions on steroids anyway. Hooks can do more than pure pre and post processing, because they're called in numerous places and give broad access to the script's data structures. Still, post processing is probably the most useful feature they implement. main character energy honestly β¨
Hooks are just Perl subroutines, which are defined in one of two files (see "FILES"). They're run at certain events during the execution of arename. The contents of the argument list for each hook depends on what hook is called (see the "List of hook events" below). However, the first argument (argument zero aka. $_[0]) to all hooks is the hook namespace, the subroutine is called in.
The global hooks file is read before the local one, which means that this local file may overwrite and extend the definitions from the global file, as much as Perl permits. This also means that hooks from the local file are run after the ones from the global file (unless you're using your own method of registering hooks; but if you do so, you know what you're doing anyway π).
Subroutines must be registered to arename, to be known as hooks. Once registered, a subroutine can be removed from the known hooks, if requested (see "Utility subroutines" below).
The keys in various data hashes passed to the hooks can be one of the following: album, artist, compilation, genre, tracknumber, tracktitle, year.
π§ Utility subroutines π§
Registration subroutines
There are two subroutines that are used to tell arename about subroutines you defined that shall become hooks.
register_hook(event, coderef)β registers a code reference (read: your subroutine) for the given event. Example:register_hook('startup', \&custom_banner);remove_hook(event, coderef)β removes all entries of the code reference for the given event. Example:remove_hook('startup', \&custom_banner);
If the coderef was added more than once, all entries are removed. clean sweep, we love to see it π
File access and manipulation
The currently processed file name can be accessed via two subroutines:
get_file()β returns the current file name as a string. This way, you can get the name of the currently processed file in every hook.set_file(file name string)β this gives you the opportunity of manipulating the current file name. Be careful using this, because if you break the file name, arename cannot work properly. π
With these, you could even change the file name of the processed file, while arename works on it (which you really should only do, if you know what you're doing). yeah bestie, only if you actually know. no cap.
User-defined-variable subroutines
Hooks can also use the data from user defined variables, via their Perl interface:
user_get(setting)β returns the current value of setting. This is always a scalar value.user_set(setting, value)β change the value of setting to value.
Here's an example for user defined settings:
# Assume, the user set the myvar-variable to "bar" in his
# configuration file
my $foo = user_get('myvar'); # $foo is now "bar"
user_set('foo', "bar, baz");
my $foo = user_get('myvar'); # $foo is now "bar, baz"
API for accessing to arename's internal configuration
You can also access the configuration data of arename itself:
get_opt(setting)β returns the current value of setting. This is always a scalar value.set_opt(setting, value)β change the value of setting to value.
So here's the tea, bestie β these are the settings arename is gonna be running with: canonicalize, dryrun, force, hookerrfatal, prefix, quiet, quiet_skip, readstdin, sepreplace, tnpad, usehooks, uselocalhooks, uselocalrc, verbose, verbosity, comp_template and template.
β οΈ Okay real talk: if you actually wanna change these settings, you should have a profound knowledge of arename's internals. Be careful. Like, no cap. π
π API for default_* settings π
If you ever need to peek at the current values of the default_* settings, here's your girl squad:
get_defaults(tagname)β hands you back the value ofdefault_tagname. β¨get_default_keys()β gives you a lexically sorted array of tag names for all thedefault_*values that are currently set.set_default(tagname, value)β sets the value ofdefault_tagnametovalue.
π¦ Miscellaneous subroutines π¦
And finally β a few misc functions that ARename.pm serves up, in case they're your vibe:
choose_template(data hash reference)β returns the appropriate template (normal versus compiliation template) based on what's in the referenced data hash.expand_template(template string, data hash reference)β returns the expanded version of template string. All the info used to do that expansion gets pulled from the referenced data hash.
π¨ Heads up queen: this function calls hooks itself. Avoid endless loops! Peep "Hooks when expanding the template" for the details.
ensure_dir(directory)β makes sure directory exists. Think:mkdir -p directoryπfile_eq(file0, file1)β checks if the name file0 and the name file1 point to the same file. Returns0if one of the file names doesn't exist or if the files don't point to the same file,1otherwise.
It dies if it can't stat one of the given files. π
tag_supported(tagname)β returns1if the tag tagname is supported by arename,0otherwise.template_deep_inspect(template_string)β this one tokenises a template string and then inspects the whole token tree, trying to figure out any potential problems lurking in it.
If tokenisation already failed, you get back a negative value. If there are any warnings with the token tree, you get zero. And if nothing came up? You get a positive value. π
This subroutine gets called for the template and comp_template strings in all sections when arename starts up. If the user decides to change a template string in a hook, it's recommended to use this function so you don't get any errors from broken templates. π«Ά
xrename(src, dest)β renames src to dest. Works across file systems too, bestie. Dies if something fails. π
π List of hook events π
This is the complete list of hook events with their descriptions, periodt.
The first argument (argument number "zero") for every hook is the name space they're called in. Wanna find out the name of the currently processed file? Use the get_file() subroutine described above. β¨
πΈ Hooks in the main loop πΈ
These hooks get called at the highest level of the script.
canonicalizeβ this one's called in the middle of the file name canonicalization process (but only if thecanonicalizesetting is set).
You can grab the current file name via get_file(). The canonicalized file name gets handed to you through the hook's arguments. The value from this argument will be assigned to the processed filename after the hook finishes running.
Arguments: 1: canonicalized file name
next_file_earlyβ called at the start of the main loop, before any file checks and canonicalizations (if enabled) are done.
Arguments:
next_file_lateβ called in the main loop after the file checks and canonicalizations are done.
In this context, "file checks" means tests for read-access and for whether the processed file is a symlink. arename will refuse to process symlinks and files it cannot read.
Arguments:
file_doneβ called in the main loop after the file has been processed (unlessfiletype_unknownwas triggered, see below π).
Arguments:
filetype_unknownβ called in the main loop after arename tried to process the file but the file type (the extension, specifically) was unknown.
Arguments:
filetype_knownβ called when it's been established that the file in question should theoretically be supported by arename.
Arguments: 1: the current file name extension 2: the file type that has been detected
pre_renameβ this one's triggered directly before the actual file renaming process kicks off. All the info about the file has been gathered at this point.
Arguments: 1: the file type, 2: the extension that will be used to assemble the target filename, 3: the data hash
π Hooks in the renaming procedure π
Once all the data has been gathered, arename goes on to actually rename the files to their new destination name (which gets generated along the way β see "Hooks when expanding the template" below).
pre_apply_defaultsβ this is the very first action taken in the renaming process. It's called even before the default values are applied.
Arguments: 1: data hash, 2: file extension
pre_templateβ called before any template expansions have been done.
Arguments: 1: data hash, 2: file extension
post_templateβ called after the template has been expanded and the new file name has been completely generated (including the destination directory prefix).
Arguments: 1: data hash, 2: file extension 3: the generated new filename (including directory prefix and file extension)
post_ensure_dirβ the destnation directory for the new file name may contain sub directories that currently don't exist. This hook gets called after it's ensured every directory portion exists.
Arguments: 1: data hash, 2: file extension 3: the generated new filename (including directory prefix and file extension)
post_renameβ the final hook in the actual renaming process. The file has been renamed at this point. β¨
Arguments: 1: data hash, 2: file extension 3: the generated new filename (including directory prefix and file extension)
π Hooks when expanding the template π
These hooks get called when the template string is being filled with the data from tags in the audio files. To pull that off, arename first tokenises the template string into a data structure, which is later used to assemble the target file name.
pre_expand_templateβ called before any expansions are done.
Arguments: 1: the template string, 2: the data hash
post_expand_templateβ called after all expansions have been done, right before the resulting string gets returned.
Arguments: 1: the template string (fully expanded), 2: the data hash
expand_template_pre_expand_tagβ called each time the value of an existing tag is expanded. This may happen more than once, since tags can be used in a template as often as the user wants. At each of those points, this hook gets called right before the data was retrieved and post-processed (like zero-padding thetracknumbertag).
Arguments: 1: the tag's name, 2: the data hash
expand_template_unknown_tagβ this hook gets called whenever arename tries to expand a tag within a template that it doesn't have any data available for.
Arguments: 1: the supposedly expanded string (undef upon hook-entry), 2: the tag's name, 2: the data hash
expand_template_post_expand_tagβ called each time the value of an existing tag is expanded. Just like with theexpand_template_pre_expand_taghook, this may happen more than once.
At each of those points, this hook gets called right after the data was retrieved and post-processed.
Arguments: 1: the value, which will be used for expansion, 2: the tag's name, 2: the data hash
π§ Hooks while gathering information π§
These hooks get triggered while the tag information is being extracted from the audio files arename is processing. It happens in two steps. First the Audio::Scan module is used to scan for the raw meta data information from the current file. Then arename's data hash gets filled with that data.
pre_scanβ called right before any scanning has been done.
Arguments: 1: the type of the file being processed (ogg for ogg vorbis files)
post_scanβ triggered as soon asAudio::Scanis done processing the current file, but before arename's data hash has been filled.
Arguments: 1: the type of the file being processed (ogg for ogg vorbis files), 2: the data structure returned by Audio::Scan
ambiguoustagβ when the data hash is being filled, it's possible that for one arename tag (likeartist) multiple values were returned byAudio::Scan. This hook gets triggered as soon as such a tag with ambiguous values is processed.
The hook may be used for maximum control over how ambiguous values are handled. To do that, the ambiguous value (passed as an array reference in the second argument) should be turned into the desired scalar value.
If the array reference is left as it is, the usual ambiguoususefirst behaviour is followed. See the option's description for details.
Arguments: 1: the name of the tag with the ambiguous value, 2: its current (ambiguous) value, 3: the data hash in its current form (obviously not all values will have been filled in at this point), 4: the data structure returned by Audio::Scan (see its documentation for details)
post_fillβ finally, thepost_fillhook gets called after the data hash has been filled. This is a good spot if you want to post-process the values of individual tags.
Arguments: 1: return code of the filling process (0 in case of an error, 1 otherwise), 2: the type of the file being processed (ogg for ogg vorbis files), 3: the data structure returned by Audio::Scan, 4: the data hash.
β Miscellaneous hooks β
apply_defaultsβ triggered before values from thedefault_*settings are applied to missing values in the audio file. This hook is only run if a default value for a tag will actually be used!
Arguments: 1: data hash, 2: current key
startupβ called directly after all the module initialisation is done, at the very start of the script. Configuration files will have been read, as well as hook files (obviously) and command line options will have been handled at this point already.
This hook may be useful for postprocessing the configuration as well as for debugging. π
normal_quitβ runs at the very end of the script, and you only get here if nothing catastrophic went down. No drama, no fatals, just a chill wrap-up. π
Arguments: 1: the program's argument list
Example
Okay so before anything else, let's vibe-check how argument passing actually works in arename hooks. Look at these two startup hooks:
sub print_banner0 {
# Yes, everything handed over to hooks (except for the namespace)
# are references. This gives us simple two way communication, but
# it's also a pretty big responsibility to handle. Think before
# screwing up. :)
my ($ns, $nameref, $verref, $confref, $suptagsref, $argvref) = @_;
print "BANNER! $$nameref $$verref " . $argvref->[0] . "\n";
# The following actually changes the $NAME variable, used
# in ARename.pm, which doesn't hurt, because it is only the
# name of the program running. For other hook events and variables,
# there might be vital data in one of the references. Be very careful
# before changing values willy-nilly.
$$nameref =~ s/name/blame/;
}
register_hook('startup', \&print_banner0);
sub print_banner1 {
my ($ns, $nameref, $verref, $confref, $suptagsref, $argvref) = @_;
# Since $NAME used to be 'arename', the substitution
# in print_banner0() will have changed $NAME to 'areblame',
# which $$nameref below will reveal.
print "ANOTHER BANNER! $$nameref $$verref\n";
}
register_hook('startup', \&print_banner1);
Not me warning you twice about the references π everything handed to hooks except the namespace is a reference, so you can write back through it. That's a whole superpower and a whole responsibility, bestie.
Now here's something actually useful, fr fr. This next hook replaces every bit of whitespace in your generated file names with underscores:
sub replace_spaces_by_underscore {
my ($templateref, $datref) = @_;
$$templateref =~ s/\s+/_/g;
}
register_hook('post_expand_template', \&replace_spaces_by_underscore);
So yeah, that absolutely does the trick β¨ but plot twist: there's an arename extension that ships with the app and was literally built for exactly this. Peep "EXTENSIONS" below for the deets on the ReplaceSpaces extension module. Obsessed.
π EXTENSIONS π
Arename rolls up with a whole lil squad of extensions implemented as Perl modules, and they're here to handle the more exotic, weird-little-guy tasks that the core module ARename.pm simply does not deal with. π
Every one of these bundled extension modules (and yes, they're all children of the ARename namespace π«Ά) is fully documented inside its own source file, and you can read all about it with the perldoc utility:
% perldoc ARename::ReplaceSpaces
Any module that implements a hook also comes with a convenience subroutine called register(), and it registers the hook code to the event the author intended. So like, to use the RenameSpaces hook, you'd drop this into your hooks file:
use ARename::ReplaceSpaces;
ARename::ReplaceSpaces::register();
Here's the full list of bundled extensions:
BailOutβ a hook that terminates arename right after it's read all the configuration files. It's designed to help you test out new settings, and it's probably not super useful for the average user. πKillNonASCIIβ this module implements a hook that strips all non-ascii characters out of your generated file names. π
It's also the extension module you wanna look at if you're interested in writing your own extension modules, because it's got all the code and documentation that an extension needs to make it into the arename package.
MP3RecodeToUTF8βMP3RecodeToUTF8is a hook that attempts to cure the problems caused by the different types of mp3 tag versions and the encoding mess that comes along with it. π
If you're on a UTF-8 based system and you're wondering why arename is producing latin1 characters for mp3 files that have non-ascii characters in their tags, this extension may be of help.
RemoveEmptySubdirsβ this module tries to remove empty directories that might have popped up because files got moved to another directory during the renaming process. π§ΉReplaceSpacesβ a hook that replaces whitespace in generated filenames with a configurable string, which defaults to a single underscore character"_".Template::Albumlessβ implements a hook to handle tracks with missingalbumtags, by offering to switch to an entirely different template for these files. πΈTNPadAdjustByAlbumβ this module lets you adjust the value of thetnpadcore setting based on patterns matched against a track'salbumtag.
The whole idea is to get proper padding on those large audiobooks that contain more than 99 tracks. π
There are also a few utility modules that implement helpful code shared among all the bundled extension modules. Some of that code might be useful for your own user defined hooks or extension modules too:
Util::Filesβ a module containing file-related utilities.Util::IsNumberβ the purpose of this module is to provide helper subroutines that check whether values look like numbers (integers, unsigned integers, etc.).Util::RegisterModuleHookβ this implements a helper to quickly create theregister()subroutine of hook extension modules.Util::VersionGuardβ this module implements a subroutine designed to detect version discrepancies between an extension module and theARename.pmcore module.
π¦ User-defined Extensions
So say you've decided that the ARename::Extension::register() idea of encapsulating extensions is a good idea, and now you wanna do that yourself too. Maybe because you just like keeping your hooks file tidy, or maybe because you wanna contribute your awesome extension code back to arename. Either way, you're gonna need a place to put your Perl code. π
Arename does NOT set such a place by default. But setting it up yourself from the hooks file is genuinely so easy:
BEGIN {
unshift @INC, $ENV{HOME} . q{/.arename};
}
That way you can place Perl modules into ~/.arename like this:
~/.arename/ARename/MyAwesomeExtension.pm
And then just use it like the bundled extensions:
use ARename::MyAwesomeExtension.pm;
ARename::MyAwesomeExtension::register();
Take a look at the KillNonASCII.pm.in file in the arename sources for details about how to write proper extensions, how to make them configurable, and how to make use of the bundled utilities so your extension is appropriate for inclusion with arename. π
π SEE ALSO
find(1),xargs(1),perldoc(1),Audio::Scan.ARename::BailOut,ARename::KillNonASCII,ARename::MP3RecodeToUTF8,ARename::RemoveEmptySubdirs,ARename::ReplaceSpaces,ARename::TNPadAdjustByAlbum.ARename::Template::AlbumlessARename::Util::Files,ARename::Util::IsNumber,ARename::Util::RegisterModuleHook,ARename::Util::VersionGuard.
π VERSION
This manual describes arename version 4.1.
β¨ AUTHOR
Frank Terbeck <ft@bewatermyfriend.org>,
Please report bugs. π (fr fr, they wanna hear about them)
π LICENCE
Copyright 2007-2017
Frank Terbeck <ft@bewatermyfriend.org>, All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS OF THE
PROJECT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
and that's the whole page, bestie!! πβ¨ This one came to you courtesy of perl v5.34.0 and it's dated 2022-02-26, which is literally when the arename(1) page was last living its best life. Go forth and rename responsibly π
π¦
π¦ where this page comes from
- debian bookworm: arename 4.1-1 Β· BSD-2-Clause
- debian trixie: arename 4.1-1 Β· BSD-2-Clause
- ubuntu noble: arename 4.1-1 Β· BSD-2-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms