tr is one of the core commands in Linux/Unix, but very few seem to have a solid grasp of it. Its basic function is to translate string content given to it via STDIN from one thing to another.
What makes this command unique is the fact that it doesn’t read from files; instead (as mentioned above), it takes input from STDIN. This may seem a bit strange at first, but it’s quite easy to get used to, as you’ll see in the examples below.
tr works is it takes two “sets” of content from the user — think of the first as the original, and the second as the replacement. Perhaps the most basic illustration of this is simply changing one character to another:
tr a b < originalfile > newfile
This would very simply change, for the entire original file, all instances of the letter a into the letter b. A slightly more complex exercise would be changing all lowercase letters in the alphabet to uppercase:
tr 'a-z' 'A-Z' < originalfile > newfile
** Notice that
tr didn’t get passed the original file as an argument. Rather, it received originalfile’s content via STDIN.
In this example, the first “set” was the lowercase a-z, and the second was the uppercase translation. That’s how it works: it takes input from somewhere and translates it using the first set to find what’ll be changed, and the second set to determine what it’ll be changed into.
Here’s another example of
tr using STDIN:
echo "0123456789" | tr "0-9" "a-z"
Here, we took text given to us from
echo and handed it to
tr via a pipe. So again, that’s how you get
tr to process information — via STDIN — not through passing it a filename. Anyway, point made.
One of the most powerful options that
tr offers is the
-d switch — which tells
tr to delete something. Ever had a garbage character showing up all throughout a file that you wanted to get rid of in one fell swoop? Well, this is a very fast way to do it. One example would be deleting the carriage return characters from Windows formatted files to make them look correct in *Nix:
tr -d '\r' < windowsfile > nixfile // delete the carriage returns
One interesting option is the ability to “squeeze” a sequence of identical characters into a single instance of it. So, if you had a the string ‘xxx’, squeezing it would make it simply ‘x’. This command, for example, would remove multiple newlines from a file and leave you with just one at a time.
tr -s '\n' < goodfile > betterfile
tr also has the ability to sterilize files by using the
-c switch in conjunction with the
-d switch. What the
-c switch does is take the complement of the supplied set. This is best shown with an example like the one below:
tr -dc 'a-z A-Z \t \n '\32'' < input > output
The complement means “the other part of”, or the part that completes what you’ve given. An easy way to think of it when used with the
-d (delete) switch, is, “Delete everything except these characters.
So in the line above we deleted everything except the upper and lowercase alphabet, newlines, and spaces (ASCII number 32).
This is useful for using a “default deny” policy for cleaning a file, i.e. instead of deleting certain things from a file, you instead delete everything except a few characters that you explicitly allow.
echo "all your base are tired of this meme" | tr 'a-z' 'n-za-m'
p>nyy lbhe onfr ner gverq bs guvf zrzr
There are a number of other options for the command, but this brief writeup covers the basics. Of course, if you’re ever in need of more detail, just consult the man page.: