nl
If the numbering options provided by cat
isn't enough for you, nl
might help you. Apart from options to customize the number formatting and the separator, you can also filter which lines should be numbered. Additionally, you can divide your input into sections and number them separately.
Default numbering
By default, nl
will prefix line number and a tab character to every non-empty input lines. The default number formatting is 6
characters wide and right justified with spaces. Similar to cat
, the nl
command will concatenate multiple inputs.
# same as: cat -n greeting.txt fruits.txt nums.txt
$ nl greeting.txt fruits.txt nums.txt
1 Hi there
2 Have a nice day
3 banana
4 papaya
5 mango
6 3.14
7 42
8 1000
# example for input with empty lines, same as: cat -b
$ printf 'apple\n\nbanana\n\ncherry\n' | nl
1 apple
2 banana
3 cherry
Number formatting
You can use the -n
option to customize the number formatting. The available styles are:
rn
right justified with space fillers (default)rz
right justified with leading zerosln
left justified with space fillers
# right justified with space fillers
$ nl -n'rn' greeting.txt
1 Hi there
2 Have a nice day
# right justified with leading zeros
$ nl -n'rz' greeting.txt
000001 Hi there
000002 Have a nice day
# left justified with space fillers
$ nl -n'ln' greeting.txt
1 Hi there
2 Have a nice day
Customize width
You can use the -w
option to specify the width to be used for the numbers (default is 6
).
$ nl -w2 greeting.txt
1 Hi there
2 Have a nice day
Customize separator
By default, a tab character is used to separate the line number and the line content. You can use the -s
option to specify your own custom string separator.
$ nl -w2 -s' ' greeting.txt
1 Hi there
2 Have a nice day
$ nl -w1 -s' --> ' greeting.txt
1 --> Hi there
2 --> Have a nice day
Starting number and increment
The -v
option allows you to specify a different starting integer. Negative integer is also allowed.
$ nl -v10 greeting.txt
10 Hi there
11 Have a nice day
$ nl -v-1 fruits.txt
-1 banana
0 papaya
1 mango
The -i
option allows you to specify a positive integer as the step value (default is 1
).
$ nl -w2 -s') ' -i2 greeting.txt fruits.txt nums.txt
1) Hi there
3) Have a nice day
5) banana
7) papaya
9) mango
11) 3.14
13) 42
15) 1000
Section wise numbering
If you organize your input with lines conforming to specific patterns, you can control their numbering separately. nl
recognizes three types of sections with the following default patterns:
\:\:\:
as header\:\:
as body\:
as footer
These special lines will be replaced with an empty line after numbering. The numbering will be reset at the start of every section. Here's an example with multiple body sections:
$ cat body.txt
\:\:
Hi there
How are you
\:\:
banana
papaya
mango
$ nl -w1 -s' ' body.txt
1 Hi there
2 How are you
1 banana
2 papaya
3 mango
Here's an example with both header and body sections. By default, header and footer section lines are not numbered (you'll see options to enable them later).
$ cat header_body.txt
\:\:\:
Header
red
\:\:
Hi there
How are you
\:\:
banana
papaya
mango
\:\:\:
Header
green
$ nl -w1 -s' ' header_body.txt
Header
red
1 Hi there
2 How are you
1 banana
2 papaya
3 mango
Header
green
And here's an example with all the three types of sections:
$ cat all_sections.txt
\:\:\:
Header
red
\:\:
Hi there
How are you
\:\:
banana
papaya
mango
\:
Footer
$ nl -w1 -s' ' all_sections.txt
Header
red
1 Hi there
2 How are you
1 banana
2 papaya
3 mango
Footer
The -b
, -h
and -f
options control which lines should be numbered for the three types of sections. Use a
to number all lines of a particular section (other features will discussed later).
$ nl -w1 -s' ' -ha -fa all_sections.txt
1 Header
2 red
1 Hi there
2 How are you
1 banana
2 papaya
3 mango
1 Footer
If you use the -p
option, the numbering will not be reset on encountering a new section.
$ nl -p -w1 -s' ' all_sections.txt
Header
red
1 Hi there
2 How are you
3 banana
4 papaya
5 mango
Footer
$ nl -p -w1 -s' ' -ha -fa all_sections.txt
1 Header
2 red
3 Hi there
4 How are you
5 banana
6 papaya
7 mango
8 Footer
The -d
option allows you to customize the two character pattern used for sections.
# pattern changed from \: to %=
$ cat body_sep.txt
%=%=
apple
banana
%=%=
red
green
$ nl -w1 -s' ' -d'%=' body_sep.txt
1 apple
2 banana
1 red
2 green
Section numbering criteria
As mentioned earlier, the -b
, -h
and -f
options control which lines should be numbered for the three types of sections. These options accept the following arguments:
a
number all lines, including empty linest
number lines except empty ones (default for body sections)n
do not number lines (default for header and footer sections)pBRE
use basic regular expressions (BRE) to filter lines for numbering
If the input doesn't have special patterns to identify the different sections, it will be treated as if it has a single body section. Here's an example to include empty lines for numbering:
$ printf 'apple\n\nbanana\n\ncherry\n' | nl -w1 -s' ' -ba
1 apple
2
3 banana
4
5 cherry
The -l
option controls how many consecutive empty lines should be considered as a single entry. Only the last empty line of such groupings will be numbered.
# only 2nd consecutive empty line will be considered for numbering
$ printf 'a\n\n\n\n\nb\n\nc' | nl -w1 -s' ' -ba -l2
1 a
2
3
4 b
5 c
Here's an example which uses regexp to identify lines to be numbered:
# number lines starting with 'c' or 't'
$ nl -w1 -s' ' -bp'^[ct]' purchases.txt
1 coffee
2 tea
washing powder
3 coffee
4 toothpaste
5 tea
soap
6 tea
See Regular Expressions chapter from my GNU grep ebook if you want to learn about regexp syntax and features.