I have a collection of notes. Unfortunately the naming scheme is not handy. When we sort the files by name, they are sorted by the number for the day of the month. Instead, we want them sorted by the year first, then the number of the month, and finally the number for the day of the month.
We start with this situation:
$ ls
02-aug-2021.txt 06-jul-2021.txt 08-jul-2021.txt 12-jul-2021.txt 15-jun-2021.txt 17-jun-2021.txt 21-jul-2021.txt 22-jul-2021.txt
23-jul-2021.txt 24-jun-2021.txt 30-jul-2021.txt 05-aug-2021.txt 07-jul-2021.txt 09-jul-2021.txt 14-jun-2021.txt 16-jun-2021.txt
18-jun-2021.txt 21-jun-2021.txt 22-jun-2021.txt 23-jun-2021.txt 25-jun-2021.txt 30-jun-2021.txt
We want to change 02-aug-2021.txt to 2021-08-02.txt. That way the filename sort order is also the chronological order.
To achieve this we install Debian's verison of the rename tool:
$ sudo apt install rename
To find out how to use a command like rename we can open the manual. Most commands do have a manual entry. We open the manual for rename by executing:
$ man rename
It will show information about the command, and the flags that we can pass it. Sometimes it also gives examples.
We can give the rename command a regex to switch the date-related parts of the filenames to new locations. Then we use the nono flag to avoid actually executing the command, and the verbose flag to see the output.
The regex needs to create a match group for two digits (group 1), then three words (group 2), and then four digits (group 3). Then we can put these match groups in their intended locations. To create the first match group for two digits, we write \d{2}. To place that match in the output, we write \$1. This is what the total regex looks like: s/(\d{2})-(\w{3})-(\d{4}).txt/\$3-\$2-\$1.txt/ The pattern on the left-hand side of the middle / is the pattern we match on, with the three match groups. The - characters will match with the - characters in the file names. The pattern on the right-hand side is the output pattern.
Let's try this out:
$ rename --nono --verbose "s/(\d{2})-(\w{3})-(\d{4}).txt/\$3-\$2-\$1.txt/" *.txt
rename(02-aug-2021.txt, 2021-aug-02.txt)
rename(05-aug-2021.txt, 2021-aug-05.txt)
...
Looks good! The output tells us that we will change 02-aug-2021.txt into 2021-aug-02.txt. Now we know the result will be good, and we can perform the command.
$ rename "s/(\d{2})-(\w{3})-(\d{4}).txt/\$3-\$2-\$1.txt/" *.txt
$ ls
2021-aug-05.txt 2021-aug-02.txt 2021-jul-06.txt 2021-jul-08.txt 2021-jul-12.txt 2021-jul-22.txt 2021-jul-30.txt 2021-jun-15.txt
2021-jun-17.txt 2021-jun-21.txt 2021-jun-23.txt 2021-jun-25.txt 2021-aug-05.txt 2021-jul-07.txt 2021-jul-09.txt 2021-jul-21.txt
2021-jul-23.txt 2021-jun-14.txt 2021-jun-16.txt 2021-jun-18.txt 2021-jun-22.txt 2021-jun-24.txt 2021-jun-30.txt
As you can see we still have one step remaining in this particular file renaming example. We also want the months as numbers. I'm quite certain that there is a number of fancy ways to do that. I am just going to do it the simple way. I will swap jul with 07, and so on.
$ rename "s/(\d{4})-jul-(\d{2}).txt/\$1-07-\$2.txt/" *.txt
... and again for the other months
$ ls
2021-06-14.txt 2021-06-17.txt 2021-06-22.txt 2021-06-25.txt 2021-07-07.txt 2021-07-12.txt 2021-07-23.txt 2021-08-05.txt
2021-06-15.txt 2021-06-18.txt 2021-06-23.txt 2021-06-30.txt 2021-07-08.txt 2021-07-21.txt 2021-07-30.txt 2021-08-10.txt
2021-06-16.txt 2021-06-21.txt 2021-06-24.txt 2021-07-06.txt 2021-07-09.txt 2021-07-22.txt 2021-08-02.txt
Mission accomplished!