Reshape text

INPUT · Slides

Swap characters, delete them (`tr`)

01 / 06

tr swaps one character for another

cut pulled out columns. tr (translate) swaps the characters themselves.

tr a-z A-Z

That means "lower case to capitals". It pairs them up one character at a time: a to A, b to B, and so on.

a-z is how you write "from a to z", the same idea as [a-z] in grep.

~ $ tr a-z A-Z < english.txtHELLO WORLDHELLO WORLD

02 / 06

tr does not take a file name

This is the biggest quirk of tr: you cannot write a file name.

tr a-z A-Z english.txt     # does not work

tr is built to read stdin (standard input) only, so you write it like this.

tr a-z A-Z < english.txt      # pour it in with <cat english.txt | tr a-z A-Z  # hand it over with a pipe

The < and the pipe from chapter 4 are genuinely required here. You may have wondered why there were two ways; tools like this are why.

03 / 06

-d deletes, -s squeezes

Besides swapping there are two flags you use a lot.

-d (delete) — remove the characters you name

tr -d 0-9 < f.txt    # remove every digit

-s (squeeze) — turn a run of the same character into one

tr -s ' ' < f.txt    # runs of spaces down to one

-s fixes the "uneven spacing" data that gave you trouble in the last lesson. Even the spacing out and cut -d" " becomes usable.

04 / 06

-s gets rid of blank lines

One more handy use of -s. Squeeze the newlines and blank lines disappear.

tr -s '\n' < blanks.txt

A blank line is just "two newlines in a row", so squeezing runs of newlines into one removes them.

\n is how you write a newline. Do not forget the single quotes, or the shell may take it for something else.

05 / 06

Capitals and lower case are different characters

Something to watch: tr treats capitals and lower case as different things.

~ $ tr -d aeiou < english.txthll wrldHELLO Wrld

The vowels went from hello world on the first line, but HELLO on the second is untouched. You wrote aeiou, so the capitals AEIOU were never in scope.

To remove both, write tr -d aeiouAEIOU.

There is no "ignore case" flag on tr like grep -i. Writing out every character you want is the way of tr.

06 / 06

Now have a go

Four files.

  • english.txthello world and HELLO World
  • csv.txta,b,c and d,e,f
  • gaps.txtone two three (uneven spacing)
  • blanks.txtaaa bbb, a blank line, a blank line, ccc

Do not forget you need a < or a pipe every time. Write a file name at tr and it will not read it. Seeing what happens when you get it wrong, once, is what makes it stick.