Print line numbers starting at zero using awk
Categories:
Print Line Numbers Starting at Zero Using Awk

Learn how to use awk
to prepend line numbers to your text files, starting the count from zero instead of the default one.
The awk
utility is a powerful text processing tool often used for data extraction and reporting. By default, when awk
is used to add line numbers, it starts counting from 1. However, there are many scenarios, especially in programming or data analysis, where zero-indexed line numbers are preferred. This article will guide you through various methods to achieve zero-indexed line numbering with awk
.
Understanding Awk's Built-in Variables
awk
provides several built-in variables that are incredibly useful for text manipulation. The most relevant for line numbering is NR
, which stands for 'Number of Record'. By default, NR
increments for each line processed, starting at 1. To achieve zero-indexed numbering, we need to manipulate this variable or introduce our own counter.
flowchart TD A[Start Awk Process] --> B{Read First Line?} B -- Yes --> C[NR = 1] B -- No --> D[NR = Previous NR + 1] C --> E[Print (NR-1) and Line] D --> E E --> F{More Lines?} F -- Yes --> B F -- No --> G[End Awk Process]
Flowchart of Awk's default NR behavior and how we modify it for zero-indexing
Method 1: Subtracting One from NR
The simplest and most direct way to get zero-indexed line numbers is to subtract 1 from NR
before printing it. This ensures that the first line (where NR
is 1) gets a '0', the second line (where NR
is 2) gets a '1', and so on.
awk '{ print NR-1, $0 }' your_file.txt
Basic awk
command to print zero-indexed line numbers.
Let's break down this command:
awk
: Invokes theawk
program.'{ print NR-1, $0 }'
: This is theawk
script.NR-1
: Calculates the current line number minus one.$0
: Represents the entire current line of input.- The comma
,
betweenNR-1
and$0
acts as the Output Field Separator (OFS), which by default is a single space.
OFS
variable. For example, awk 'BEGIN {OFS=": "} { print NR-1, $0 }' your_file.txt
would use a colon and a space.Method 2: Using a Custom Counter Variable
While subtracting from NR
is effective, another approach is to initialize and increment your own counter variable. This gives you more explicit control over the numbering logic, especially if you need more complex numbering schemes later.
awk 'BEGIN {i=0} { print i++, $0 }' your_file.txt
Using a custom variable i
for zero-indexed line numbering.
Explanation of this command:
BEGIN {i=0}
: TheBEGIN
block is executed once beforeawk
starts processing any input lines. Here, we initialize our custom counteri
to 0.{ print i++, $0 }'
: For each line:i++
: Prints the current value ofi
(which starts at 0) and then incrementsi
for the next line. This is a post-increment operation, ensuring the current line gets the '0' beforei
becomes '1'.
BEGIN
block is crucial when you need to set up variables or perform actions before processing the first line of input. Similarly, an END
block can be used for final summaries or cleanup.Handling Empty Lines and Formatting
Both methods discussed will number every line, including empty ones. If you wish to skip numbering empty lines or apply specific formatting, awk
provides the flexibility to do so.
# Skip numbering empty lines (Method 1 variant)
awk 'NF > 0 { print NR-1, $0 }' your_file.txt
# Skip numbering empty lines (Method 2 variant)
awk 'BEGIN {i=0} NF > 0 { print i++, $0 }' your_file.txt
# Format with leading zeros for numbers up to 999
awk '{ printf "%03d %s\n", NR-1, $0 }' your_file.txt
Advanced awk
commands for conditional numbering and formatting.
In the examples above:
NF > 0
: This condition checks if the number of fields (NF
) in the current line is greater than zero. An empty line hasNF
equal to 0, so this effectively skips empty lines.printf "%03d %s\n", NR-1, $0
: Usesprintf
for formatted output."%03d"
: Formats the number as a decimal integer, padded with leading zeros to a width of 3 characters (e.g., 000, 001, 010)."%s"
: Prints the string (the line content)."\n"
: Adds a newline character, asprintf
does not add one by default.