VMware ESXi and vSphere Cluster Management

Number Lines in a File with the Linux nl Command

Learn how to use Linux nl to number nonblank or every line, select lines with patterns, customize separators, alignment, padding, increments, and output files.

The Linux nl command reads text and writes it to standard output with configurable line numbers. Standard output is the stream normally displayed in your terminal. You can use nl to inspect configuration files, reference exact lines during code or log reviews, and prepare readable text for documentation.

nl does not change its input file. It produces a numbered view. The source is changed only if you deliberately use shell redirection to write output to a file, and redirecting to the same input file can destroy the original.

Prerequisites and Basic Syntax

You should be comfortable navigating files, reading text from a shell, using options and arguments, and working with standard input, pipes, output redirection, shell quoting, and introductory regular expressions.

nl [options] [file]

For example, display notes.txt with the default numbering rules:

nl notes.txt

A command can also read standard input. Standard input is the stream a command receives from a pipe or from the terminal:

cat notes.txt | nl

In practice, piping another command into nl is useful when you want to number filtered or generated output.

Default Numbering Behavior

By default, nl numbers nonblank body lines. A blank line contains no characters. A body line is an ordinary content line in nl terminology, as opposed to special header or footer sections that can be represented with delimiter conventions.

The default sequence starts at 1 and increases by 1. Blank body lines are printed, but they normally do not receive a number.

$ printf 'alpha\n\nbeta\n' > notes.txt
$ nl notes.txt
     1  alpha

     2  beta

The number field is separated from the content by whitespace by default. The exact spacing can be customized with -s.

Number Every Line with -b a

The -b option selects a body-numbering style. The style a means “all”: number every body line, including blank lines.

$ nl -b a notes.txt
     1  alpha
     2
     3  beta

This differs from the default style, commonly represented by -b t, which numbers nonempty lines:

nl -b t notes.txt

Use -b a when physical line positions matter, such as when discussing an empty line in a configuration file or preserving a one-to-one reference to every input line.

Common nl Options

OptionPurposeExample
-b aNumber all body lines, including blank lines.nl -b a notes.txt
-b tNumber nonempty body lines; this is the usual default.nl -b t notes.txt
-b nDo not number body lines, while still printing them.nl -b n notes.txt
-b pREGEXPNumber body lines matching a regular expression.nl -b 'p^T' notes.txt
-i NUMBERIncrease each successive displayed number by NUMBER.nl -i 5 notes.txt
-v NUMBERSet the first displayed number.nl -v 100 notes.txt
-s STRINGSet the text between a number and its line.nl -s ': ' notes.txt
-n FORMATSelect number alignment and zero-padding style.nl -n rz notes.txt
-w WIDTHSet the number-field width.nl -w 4 notes.txt

Changing the Number Increment

The -i option changes the amount added between consecutive numbered lines. It changes only the displayed labels; it does not insert, remove, or modify lines in the file.

nl -i 5 notes.txt

If the first numbered line is 1, the displayed sequence is 1, 6, 11, and so on. With the default nonblank rule, the increment is applied when the next numbered line is encountered, so an unnumbered blank line does not consume a displayed number.

Changing the Starting Number

Use -v to choose the initial displayed number. Combine it with -i when continuing a numbering sequence from an earlier section:

nl -v 100 -i 10 notes.txt

The first numbered line is labeled 100, the next is 110, then 120, and so forth. This is useful when a document or report is being processed in sections and the new section should continue a known numbering scheme.

Customizing the Separator

The -s option changes the separator placed between the number and the line content. A separator can be a colon, period, tab-like spacing, or any other text.

nl -s ': ' notes.txt
nl -s '. ' notes.txt
nl -s ' > ' notes.txt
nl -s $'\t' notes.txt

Quote separators that contain spaces or shell-special characters. Without quotes, the shell may split the separator into multiple arguments or interpret special characters before nl receives them.

nl -s ': ' notes.txt

In shells that support ANSI-C quoting, $'\t' passes a tab character. Otherwise, use a quoted separator appropriate to your shell.

Selecting Which Lines Receive Numbers

The -b option controls which body lines receive numbers. The input lines are still printed unless another command filters them first.

Number nonempty, all, or no lines

  • -b t numbers nonempty lines. This is the default behavior.
  • -b a numbers every line, including blank lines.
  • -b n numbers no body lines.

For example:

nl -b t notes.txt
nl -b a notes.txt
nl -b n notes.txt

Pattern-based numbering with -b pREGEXP

A regular expression is a pattern notation used to select text that meets specified conditions. With -b pREGEXP, nl numbers only body lines matching the expression. Lines that do not match are still printed without numbers.

nl -b 'p^T' notes.txt

Here, ^T means a line beginning with the character T. The single quotes protect the pattern from shell interpretation.

To match lines beginning with the word TODO:

nl -b 'p^TODO' notes.txt

Pattern matching is sensitive to the actual text. Case, leading whitespace, and anchors such as ^ and $ affect the result. If you need to number only matching lines and discard all others, filter first; pattern mode by itself keeps unmatched lines in the output.

Formatting Line Numbers

The -n option selects the line-number format. Alignment describes where digits sit inside the allocated number field. Left justified means aligned against the field’s left edge. Right justified means aligned against its right edge. Leading zeros are zero characters added before a number to fill a fixed width.

FormatAlignmentLeading ZerosIllustrative Result
lnLeft justifiedNo1 , 12 , 123
rnRight justifiedNo 1, 12, 123
rzRight justifiedYes0001, 0012, 0123
nl -n ln notes.txt
nl -n rn notes.txt
nl -n rz -w 4 notes.txt

Right alignment makes numbers line up at their right edge, which is useful when comparing values with different digit counts. Zero-padded output gives every label the same visible length and can be useful in generated reports.

Setting the Number Field Width

The -w option sets the width reserved for the number. For a file expected to contain many lines, a wider field prevents the layout from becoming cramped as the number of digits grows.

nl -n rz -w 4 notes.txt

With a width of 4 and zero padding, early labels appear as 0001, 0002, and so on. The width affects formatting, not the input data. Choose a width large enough for the largest expected line number.

Using Pipes and Standard Input

A pipe, written as |, passes one command’s standard output to another command’s standard input. This lets you number the result of a search or transformation rather than a complete file.

grep -i 'error' application.log | nl -b a

This command searches for case-insensitive occurrences of error, then numbers every resulting line. The numbers refer to the filtered output, not the original line positions in application.log. If original file positions are required, use a tool or command arrangement that preserves those positions.

Saving Numbered Output

Shell redirection sends command output somewhere other than the terminal. The > operator writes output to a file:

nl -b a notes.txt > numbered-notes.txt

This preserves notes.txt and creates a generated numbered view in numbered-notes.txt. Remember that the result contains added labels, so it may no longer be suitable as the original data file for another program.

nl Compared with cat -n and cat -b

cat -n is a convenient simple alternative that numbers every line. cat -b numbers nonblank lines. For basic display, either may be sufficient. nl is preferable when you need configurable body rules, regular-expression selection, custom increments, starting values, separators, alignment, or zero padding.

CommandDefault Handling of Blank LinesPattern SelectionFormatting ControlBest Use
nlSkips blank lines by default; configurable.Yes, with -b pREGEXP.Increment, starting value, separator, alignment, padding, and width.Custom numbering and formatted inspection.
cat -nNumbers every line.No built-in nl-style pattern rule.Limited for line-number formatting.Quick all-line numbering.
cat -bSkips blank lines.No built-in nl-style pattern rule.Limited for line-number formatting.Quick nonblank-line numbering.

Troubleshooting

Blank lines do not have numbers

The default rule skips blank body lines. Use:

nl -b a FILE

If a file contains no blank lines, default output and all-line output can look identical. Test with a file containing an empty line when checking this behavior.

The pattern numbers fewer lines than expected

The regular expression may not match because of capitalization, leading whitespace, or an incorrect anchor. Check the pattern with grep, then adjust ^ or $ as needed. Quote the expression:

grep '^TODO' notes.txt
nl -b 'p^TODO' notes.txt

The separator causes an error or loses characters

Spaces and shell-special characters must be passed as one quoted argument:

nl -s ': ' FILE

The numbers are not aligned correctly

Use rn or rz for right alignment and choose an adequate width:

nl -n rn -w 5 FILE
nl -n rz -w 5 FILE

The original file was emptied or replaced

This usually results from redirecting output to the same path as the input. Use a different output file, verify it, and only then decide whether to replace the source.

nl is unavailable

Check whether the command is on your PATH:

command -v nl

If it is missing, install the operating system package that provides the standard core text utilities.

Getting Help

nl --help
man nl

The help output is useful for a quick option summary. The manual page provides the full description of numbering styles, delimiters, and formatting behavior on your system.

Exam-Relevant Notes

  • nl FILE numbers nonblank body lines by default, starting at 1 and increasing by 1.
  • nl -b a FILE numbers every body line, including blank lines.
  • -i changes the increment; -v changes the starting value.
  • -s changes the separator, and quoted arguments are required when separators contain spaces or shell-special characters.
  • -b pREGEXP numbers matching lines while still printing unmatched lines without numbers.
  • -n ln, -n rn, and -n rz select left alignment, right alignment, and right alignment with leading zeros.
  • -w controls the width of the number field.
  • Redirection creates a generated output view; never redirect into the same file being read.

For a concise reference, see numbering lines in a file with Linux.