How to rename files to specific string in their filenames
I have large amount of .json files that need to be renamed to a specific string of numbers in each file’s name. They follow the format:
[Artist] Title (Date) [Language][Publisher][Website.####][Pages].json
"####" represents a unique numerical ID which I need to rename each file to, ranging from 1-4 characters long. It should look like this:
####.json
How can I achieve this?
With zsh
:
autoload -Uz zmv
zmv -n '*[*.(<->)][*(.json)' '$1$2'
Remove the -n
(dry-run) if happy.
The zmv
autoload
able function takes two arguments:
- a zsh extended glob pattern
- a replacement specification
It finds the files that match the pattern, here all the non-hidden ones in the current directory that contain in sequence:
*
any number of characters (or bytes)[
a literal[
*
any number of characters (or bytes).
a literal.
<->
any sequence of ASCII decimal digit (<x-y>
matches on sequences of ASCII decimal digits representing numbers from x to y)][
:][
literally.*
any number of characters (or bytes).json
: literally.
In the replacement, $1
expands to what was matched inside the first pair of (...)
, so the number matched by <->
and $2
to the second (.json
).
Note that as those *
match greedly, it will find that number in the rightmost pair of [...]
whose contents ends in .<digits>
(excluding the last). For instance in [a.1][a.2.3][x][y][z].json
, it will extract 3
even though that’s not in the second-last pair of [...]
s.
If that’s a problem, you can change it to:
zmv -n '*.(<->)][[^][]#](.json)' '$1$2'
Where [^][]#
matches on 0 or more characters (or non-characters) other than [
and ]
.