When reading complex configuration files, lengthy source code scripts, or dense server logs in the Linux terminal, finding specific information can be visually overwhelming. Without a frame of reference, instructing a colleague to “look at the error somewhere near the middle of the file” is incredibly inefficient.
While text editors like nano and vim can display line numbers, you often do not want to risk opening a critical production file in an editor just to read it. To quickly print a text file to the terminal with sequential line numbers attached to every row, Linux provides the nl (Number Lines) command.
Basic Usage of the nl Command
The nl command operates similarly to the standard cat command (which prints file contents to the screen), but it automatically prepends a formatted line number to the output.
To view a file named script.sh with line numbers, type:
nl script.sh
The terminal will print the entire file, looking something like this:
1 #!/bin/bash
2 echo "Starting backup process"
3 tar -czf backup.tar.gz /var/www/html
4 echo "Backup complete"
By default, nl is intelligent: it ignores completely blank lines. In the example above, the empty line between the two echo commands does not receive a number. This is incredibly helpful when reading code, as it only numbers the lines containing actual instructions.
Numbering Every Single Line (Including Blanks)
If you are reviewing a file where whitespace is critical, or you simply prefer strict, absolute line numbering, you can override the default behavior and force nl to assign a number to completely empty lines.
You do this using the -b a flag (which stands for “body numbering: all”):
nl -b a script.sh
Now, the output will count the empty whitespace, ensuring that line 4 is always physically the fourth line in the file, regardless of content.
Combining nl with Other Commands
The true power of nl emerges when you pipe it together with other terminal utilities. Printing a 5,000-line log file to the screen with numbers is useless because it will immediately scroll past your vision.
Instead, pipe the output of nl into a pager like less, which allows you to scroll through the numbered output at your own pace:
nl /var/log/syslog | less
Alternatively, you can use nl in conjunction with the grep command to search for specific errors, and instantly know exactly which line number in the original file generated the problem:
nl /var/log/syslog | grep "error"
This pipeline reads the file, numbers every line, and then searches for the word “error”. The resulting output will show you only the lines containing the error, alongside their precise, original line numbers, making troubleshooting vastly more efficient.