Revved up like a deuce

Today I needed to reverse a string. Someone had decided to take an easy-to-remember mix of words and numbers, reverse it, and use that as a password for a service that several people would use, including me. Let’s not argue about whether that’s a good way to set a password—I had to use it regardless.

Since my passwords are saved in the Passwords app, I only had to type this monstrosity once, but I felt there had to be an easy way for me to type it forward and have my Mac reverse it. And there is.

I knew about the tac command (that’s “cat” in reverse) because it’s part of how ANIAT is built and updated. But tac reverses the order in which the lines of its input are printed; it doesn’t reverse the lines themselves. In other words, if I have this on my clipboard,

First line
Second line
Third line
Fourth line

(with a newline at the end), then

pbpaste | tac

will output

Fourth line
Third line
Second line
First line

This is not what I wanted.1 What I wanted was the more prosaically named rev, which reverses each individual line of its input. So with the same stuff on the clipboard as above,

pbpaste | rev

will output

enil tsriF
enil dnoceS
enil drihT
enil htruoF

With rev, the lines themselves are reversed but printed in the original order.

Since I had only a single string to reverse, I used the here string syntax to send it to rev. For example,

rev <<< longagoandfaraway

produces

yawarafdnaogagnol

If this isn’t the name of a Tolkein character, it should be.

One of the nice things about rev is that it isn’t limited to ASCII.

rev <<< 'café façade'

produces

edaçaf éfac

Sadly, this only works if the non-ASCII characters are single glyphs. If your string is put together with combining characters, as in

rev <<< 'Spın̈al Tap'

what you’ll get upon reversal is the combining character in the wrong spot:

paT länıpS 

How do I know the “n̈” in Spın̈al Tap is not a single glyph? Because there is no such character. No language has an “n” with an umlaut, so it’s not in Unicode.2

Going back to our four-line example, to get lines in reverse order and individually reversed, you pipe the clipboard through both tac and rev.

pbpaste | tac | rev

produces

enil htruoF
enil drihT
enil dnoceS
enil tsriF

If the input has a trailing newline, it doesn’t matter whether tac or rev comes first.

pbpaste | rev | tac

generates the same output. But if there’s no trailing newline, the outputs will differ, and you won’t like one of them. Try it and see.


  1. If you have a use for tac, please note that it doesn’t come with macOS. You’ll have to install it another way. I use Homebrew, where tac is part of the coreutils formula

  2. Typing “Spın̈al Tap” is easy for me. For many years I’ve had a text expansion that generates it whenever I type ;tap. It’s one of my most important expansions.