swapcase with the tr command
Want to easily swap the case of some string on the *nix command line? The
tr command can do that!
You may already know the
tr command can switch lowercase to uppercase
$ echo "HI there" | tr '[:lower:]' '[:upper:]' HI THERE
Or uppercase to lowercase
$ echo "HI there" | tr '[:lower:]' '[:upper:]' | tr '[:upper:]' '[:lower:]' hi there
But we can take it further and tell
tr not only switch all lowercase to uppercase but all uppercase to lowercase in one transform!
$ echo "HI there" | tr '[:lower:][:upper:]' '[:upper:][:lower:]' hi THERE
And because we’re using character classes and not simply
a-zA-Z that means unicode letters work as well.
$ echo "CAfé" | tr "[:lower:][:upper:]" "[:upper:][:lower:]" caFÉ
This works because the arguments to
tr are a paired list of transforms. Each character in string1 (the first argument) will be replaced with the corresponding index of the character from string2 (the second argument)
$ echo crab | tr abc ABC CrAB
The above command has
abc for the first string and
ABC for the second. That means
tr will pair them up like so
a => A b => B c => C
tr perform a swapcase means making those strings include both uppercase and lowercase characters. If we were to pick randomly from the translation pairs it could look like this.
P => p k => K X => x x => X W => w M => m F => f
Why do this? Well for me I wanted a list of lowercase letters, uppercase letters, and numbers.
printable-ascii can easily provide me with that list but I wanted to go from lowercase to uppercase to numbers. But ASCII order has uppercase first.
$ printable-ascii --letters --digits --compact ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
I could tell
printable-ascii more explicitly how to order the output by manually defining the ranges in the order I want
$ printable-ascii --range a-z --range A-Z --digits --compact abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
tr command can easily do that work for me. And since I’m dealing explicitly with ASCII I can simply use
$ printable-ascii --letters --digits --compact | tr A-Za-z a-zA-Z abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789