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 theawkprogram.'{ print NR-1, $0 }': This is theawkscript.NR-1: Calculates the current line number minus one.$0: Represents the entire current line of input.- The comma
,betweenNR-1and$0acts 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}: TheBEGINblock is executed once beforeawkstarts processing any input lines. Here, we initialize our custom counterito 0.{ print i++, $0 }': For each line:i++: Prints the current value ofi(which starts at 0) and then incrementsifor the next line. This is a post-increment operation, ensuring the current line gets the '0' beforeibecomes '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 hasNFequal to 0, so this effectively skips empty lines.printf "%03d %s\n", NR-1, $0: Usesprintffor 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, asprintfdoes not add one by default.