Print Text Files with Line Numbers: nl, cat, and More
The nl command is purpose-built for adding line numbers to text files:
nl text-file
By default, nl numbers all non-empty lines and skips blank lines. This behavior is controlled by the body section style, which defaults to t (text only).
Common nl options
Number all lines including blanks:
nl -ba text-file
Start numbering at a specific value:
nl -v 100 text-file
Control number formatting:
# Right-aligned with leading zeros (width 6)
nl -nrz text-file
# Left-aligned
nl -nln text-file
# Left-aligned, no leading zeros
nl -nln text-file
Change the separator between number and content:
# Use colon and space instead of default tab
nl -s ': ' text-file
# Use pipe separator
nl -s ' | ' text-file
Set line number field width:
# Narrow field (4 characters)
nl -w 4 text-file
# Wide field (8 characters)
nl -w 8 text-file
Number only lines matching a pattern:
# Only number lines starting with uppercase letter
nl -bp'^[A-Z]' text-file
# Number lines containing "error"
nl -bp'error' text-file
Quick alternatives
cat -n for simple numbering:
cat -n text-file
This numbers all lines without blank-line distinction. It’s simpler but less flexible than nl. Good for quick one-offs.
grep -n to number while filtering:
grep -n "pattern" text-file
Restricts output to matching lines only. Useful when you need both filtering and line numbers in a single pass.
less -N for interactive viewing:
less -N /path/to/largefile
Displays line numbers within the pager. Press & in less to toggle line numbers on/off without exiting. Essential for navigating large log files.
awk for custom formatting:
awk '{print NR": "$0}' text-file
# With custom separators
awk '{printf "%5d | %s\n", NR, $0}' text-file
# Number only non-empty lines
awk 'NF {printf "%d: %s\n", NR, $0}' text-file
The awk approach gives you full control over output formatting and filtering logic.
sed for in-place numbering:
sed = text-file | paste -d ' ' - -
This uses sed to insert line numbers, then paste to align them. Less common but useful for scripting.
Practical examples
Number a log file and save output:
nl /var/log/syslog > syslog-numbered.txt
View a configuration file with line numbers, skipping blanks:
nl -s ': ' /etc/nginx/nginx.conf | less
Find error lines with context and line numbers:
nl -ba /var/log/app.log | grep -i error
Number a Python script with narrow field width:
nl -w 3 -s ' | ' script.py
Number specific line ranges:
# Lines 10-50 with numbers
sed -n '10,50p' file.txt | nl -v 10
Combine with head/tail for partial numbering:
# Number only the first 20 lines
head -20 file.txt | nl
# Number the last 30 lines
tail -30 file.txt | nl -v $(wc -l < file.txt | awk '{print $1-29}')
Compare files side-by-side with line numbers:
diff <(nl file1.txt) <(nl file2.txt)
Choosing the right tool
- Use
nlwhen you need control over blank lines, formatting, and numbering patterns - Use
cat -nfor quick numbering of entire files - Use
grep -nwhen you’re already filtering output - Use
less -Nwhen viewing files interactively - Use
awkwhen you need complex custom formatting or conditional numbering
