Tips for the nl command

nl is surprisingly versatile and a good choice if you need to add a unique ID field to a data table (as described here).

(See also this BASHing data post.)

Add line numbers

The nl command numbers the lines in a text file, or in standard input:

$ echo -e "aaa\nbbb\nccc"
$ echo -e "aaa\nbbb\nccc" | nl
     1    aaa
     2    bbb
     3    ccc

Notice above that the line numbers look indented. You can think of the numbering as a set of columns, with the right-most column holding the line number, and the other columns blank. As the numbers get bigger, they occupy more columns to the left ('23' occupies 2 columns, '147' occupies 3 columns, etc). In other words, the line numbering is right-justified. The blank columns can be filled with leading zeroes using the '-nrz' option:

$ echo -e "aaa\nbbb\nccc" | nl -nrz
000001    aaa
000002    bbb
000003    ccc

The default number of columns used by nl is 6, which allows for line numbering from 000001 to 999999. The '-w' option sets the number of columns. With 4 columns you could number lines from 0001 to 9999:

$ echo -e "aaa\nbbb\nccc" | nl -nrz -w4
0001    aaa
0002    bbb
0003    ccc

If you don't want leading zeroes, you can avoid indentation by setting '-w' to 1 column. When line numbers get bigger than 9, the numbers will automatically be left-justified.

$ echo -e "aaa\nbbb\nccc" | nl -w1
1    aaa
2    bbb
3    ccc 

Remove line numbers

By default, nl separates line numbers from line text with one tab character. Since the cut command uses tabs as default field separators, you can remove that first, tab-separated field with cut:

$ cat table
1    aaa    ddd
2    bbb    eee
3    ccc    fff
$ cut -f2- table
aaa    ddd
bbb    eee
ccc    fff
$ cut -f1 --complement table
aaa    ddd
bbb    eee
ccc    fff  

More options

You can control how nl separates line numbers from line text by setting the '-s' option to any string, such as 2 tabs:

$ echo -e "aaa\nbbb\nccc" | nl -w1 -s$'\t'$'\t'
1        aaa
2        bbb
3        ccc

or a word with leading and trailing spaces:

$ echo -e "aaa\nbbb\nccc" | nl -w1 -s" foo "
1 foo aaa
2 foo bbb
3 foo ccc

or a numbering convention, like a round bracket and a space:

$ echo -e "aaa\nbbb\nccc" | nl -w1 -s") "
1) aaa
2) bbb
3) ccc

or even a linefeed character, which will put the line number on a new line before the line it numbers:

$ echo -e "aaa\nbbb\nccc" | nl -w1 -s$'\n'

You can also control how nl does its numbering. The '-v' option sets the starting number (the default is 1) and the '-i' option sets the increment (the default is 1):

$ echo -e "aaa\nbbb\nccc" | nl -w1 -v0 -i2
0    aaa
2    bbb
4    ccc

An alternative to nl for numbering lines is the cat command with its '-n' option, but cat -n only does the default nl numbering, with 6 columns, numbers right-justified and a tab between the line number and the line text.