Reshape text

INPUT · Slides

Line them up side by side, number them (`paste` and `nl`)

01 / 06

This time you join sideways

Think back over the tools so far.

  • grep — pick the lines you want (cut across)
  • cut — pull out the columns you want (cut down)
  • sort and uniq — reorder lines, gather them up

Every one of them reduces or reorders.

This lesson goes the other way, with paste, which joins separate files side by side, and nl, which adds line numbers. Tools that add rather than take away.

02 / 06

paste puts lines side by side

paste lines up two or more files by line number.

~ $ paste names.txt scores.txttanaka  80suzuki  95sato    72

The file of names and the file of scores paired up, line by line.

The separator is a tab by default. -d changes it, so to build a CSV you write this.

paste -d, names.txt scores.txt

Remember that cat names.txt scores.txt would give you six lines stacked up. cat goes down, paste goes across.

~ $ paste -d, names.txt scores.txttanaka,80suzuki,95sato,72

03 / 06

-s turns down into across

Add -s (serial) and all the lines of one file become a single line.

~ $ paste -s -d, names.txttanaka,suzuki,sato

What was stacked up is now one line across.

In the last lesson you used tr to turn something sideways into something stacked. paste -s goes the other way.

What you wantTool
across to downtr ' ' '\n'
down to acrosspaste -s -d' '

Learn those two and you can turn data whichever way you need.

04 / 06

nl numbers the lines

nl (number lines) puts a line number at the front of each line.

nl names.txt

You can change the width and the separator. The default is right aligned and hard to read, so this is easier.

nl -w1 -s': ' names.txt
  • -w1 — one digit of width (no padding spaces)
  • -s': ' — put : after the number

There is also -v10 to start at ten, and -i5 to step by five.

~ $ nl -w1 -s': ' names.txt1: tanaka2: suzuki3: sato

05 / 06

How nl differs from cat -n

There is another way to number lines: cat -n. But the result differs.

blanks.txt is three lines: aaa, a blank line, bbb.

~ $ nl blanks.txt     1  aaa     2  bbb~ $ cat -n blanks.txt     1  aaa     2     3  bbb

nl does not count blank lines. cat -n does.

Which you want depends on the situation.

  • numbering a piece of writing (blank lines are decoration, not to be counted) → nl
  • finding which line of the file something is on (you want the real number) → cat -n

Write nl -ba and nl counts the blanks too (b for body, a for all).

06 / 06

Now have a go

Three files.

  • names.txttanaka, suzuki, sato
  • scores.txt80, 95, 72
  • blanks.txtaaa, a blank line, bbb

names.txt and scores.txt line up with each other. Line one goes with line one (tanaka and 80).

paste pairs purely by line number, so if the order does not match you get the wrong pairs. Get into the habit of cat-ing both files first to check the order lines up.