|||

Rake Routes

by Stephen Ball

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

Having 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

But the tr command can easily do that work for me. And since I’m dealing explicitly with ASCII I can simply use a-zA-Z

$ printable-ascii --letters --digits --compact | tr A-Za-z a-zA-Z
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
Up next nice go test output The go test command is alright and props to go for being like a real modern language with built-in support for testing. But its output is decidedly A subtle Go bug that types cannot help with I ran into this bug while going through the highly excellent “Powerful Command-Line Applications in Go” by Ricardo Gerardi The following
Latest posts Where did the recent Elixir posts go? A subtle Go bug that types cannot help with swapcase with the tr command nice go test output See where vim settings came from Containers in the real world and backpressure in distributed systems Elixir Phoenix and “role postgres does not exist” From awk to a Dockerized Ruby Script Finding leap years with the cal command The Problem of State Clojure Functions in Four Ways See Some Clojure A simple language spec isn’t a feature when you’re building applications The Fastest Possible Tests Shrink your data into bitfields (and out again) Every “if” statement is an object waiting to be extracted Choose Generic Tools Hyperlinks you might find interesting — #4 Running bundle install on rails master Use tldr for command line examples Friday Lunch Links — #3 Friday Lunch Links — #2 Logical Solver: Turn facts into conclusions Programming with jq Command line tools - jq Friday Lunch Links — #1 Why diversity matters Music for coding - October 2019 Code puzzles are a poor way to gauge technical candidates Add vim to a pipeline with vipe Connecting Objects with Observable