Ok, so thanks to @Prvt_Yadv I was able to understand the dots. Here's the first question answer:
What's the magic behind the second tr
command?
The 13 dots are simply being mapped to the first 13 letters from the second set. So
tr .............A-Z A-ZA-Z
will produce the following sets:
SET1 -> .............ABCDEFGHIJKLMNOPQRSTUVXWYZ
SET2 -> ABCDEFGHIJKLMNOPQRSTUVXWYZABCDEFGHIJKLMNOPQRSTUVXWYZ
If your input doesn't contain a dot, you can discard the initial sequence, since you won't use those substitution. Then the sets would become:
SET1 -> ABCDEFGHIJKLMNOPQRSTUVXWYZ
SET2 -> NOPQRSTUVXWYZABCDEFGHIJKLMNOPQRSTUVXWYZ
But since the first set already contains all 26 letters and set2 has repeating trailing letter, those are discarded too, finally becoming
SET1 -> ABCDEFGHIJKLMNOPQRSTUVXWYZ
SET2 -> NOPQRSTUVXWYZABCDEFGHIJKLM
Which is the rot13 substitution and identical to the first command (except for not dealing with lower cases here). The same logic can be applied for the title of the question:
tr ...A-Z A-ZA-Z <<< “JVPQBOV”
would produce the sets:
SET1 -> ...ABCDEFGHIJKLMNOPQRSTUVXWYZ
SET2 -> ABCDEFGHIJKLMNOPQRSTUVXWYZABCDEFGHIJKLMNOPQRSTUVXWYZ
Discarding the initial sequence and the trailing repeating letters they become:
SET1 -> ABCDEFGHIJKLMNOPQRSTUVXWYZ
SET2 -> DEFGHIJKLMNOPQRSTUVXWYZABC
Which is the rot3 substitution.
Now for the second question:
How to make the second command work for both lower and upper case, just like the first command?
To make it work you put the desired number of dots at the beginning, matching your rot and 26 dots between to upper sequence and the lower sequence, just like this:
tr ........A-Z..........................a-z A-ZA-Za-za-z
This would successfully create an insensitive rot8. To visualize why this works let's see the sets:
SET1 -> ........ABCDEFGHIJKLMNOPQRSTUVXWYZ..........................abcdefghijklmnopqrstuvxwyz
SET2 -> ABCDEFGHIJKLMNOPQRSTUVXWYZABCDEFGHIJKLMNOPQRSTUVXWYZabcdefghijklmnopqrstuvxwyzabcdefghijklmnopqrstuvxwyz
Excluding the dots mapping and trailing letters:
SET1 -> ABCDEFGHIJKLMNOPQRSTUVXWYZabcdefghijklmnopqrstuvxwyz
SET2 -> IJKLMNOPQRSTUVXWYZABCDEFGHijklmnopqrstuvxwyzabcdefgh
Now it works for both upper and lower case :)
Another way to make it works is to use two tr
commands as follow:
tr .............A-Z A-ZA-Z <<< "ABJ V hqrefgnaq" | tr .............a-z a-za-z
A caveat to using the dots substitution was gave by @iruvar: this command will not work as expected when the input string has dots. This is because the dots are being mapped to other letters and when doing the substitution, tr
will change the input dot to the last mapped letter. But you can actually use any other character than dots. So, if using dots in your tr
command is a problem, you can use @
instead, for example. This would work just as fine:
tr @@@@@@@@@@@@@A-Z A-ZA-Z <<< "GUNAX LBH NYY..."
tr [.*13].A-Z A-ZA-Z
works just as well astr .............A-Z A-ZA-Z