The Three Phases of an AWK Program
An AWK program executes in three phases. The BEGIN block runs exactly once before the first record is read, making it the natural home for initialization: setting FS, printing column headers, seeding variables, or configuring OFS. The main rules run once per input record. Finally, the END block runs exactly once after the last record has been processed, ideal for printing totals, averages, or summaries accumulated during the main phase. Both BEGIN and END are optional and use the special keyword patterns BEGIN { ... } and END { ... }; a program may even consist solely of a BEGIN block, in which case AWK never reads input at all.
Cricket analogy: BEGIN is the pre-match team talk and pitch inspection, the main rules are each ball bowled, and END is the post-match presentation where the final scorecard and player-of-the-match are announced.
Using BEGIN for Setup and Headers
The BEGIN block is where you prepare the environment before data arrives. Because no record has been read yet, $0 and the fields are empty and FILENAME is unset, but you can still assign FS, OFS, RS, and ORS here so they apply to the very first record. It is the correct place to print a table header, initialize counters to zero (though AWK auto-initializes numeric variables to 0 and strings to empty), or read configuration. A BEGIN-only program is a legitimate way to use AWK as a calculator or formatter, for example awk 'BEGIN{print 2^10}' prints 1024 without touching any input file.
Cricket analogy: Setting FS in BEGIN is like the groundstaff marking the crease before play — you define the boundaries once, up front, so every delivery is judged consistently.
Using END for Aggregation and Reporting
The END block sees the results of the entire run. Inside END, NR holds the total number of records processed and $0 retains the last record read in most AWK implementations, which is useful for printing the final line or a grand total. This is where you emit computed statistics: sums accumulated in the main rules, averages computed as sum/NR, maximums tracked with comparisons, or counts stored in associative arrays that you loop over with for (key in arr). A classic pattern is accumulating in the main block and reporting in END, keeping the per-record logic simple and the summary logic separate.
Cricket analogy: END is the scorer computing the final run rate (sum/NR) and top scorer after the last ball — all the per-ball tallies come together into one summary.
# Sum column 2 and report the average at the end
awk 'BEGIN { print "Processing..."; total = 0 }
{ total += $2; count++ }
END { printf "Sum: %d, Average: %.2f over %d records\n", total, total/NR, NR }' data.txt
# BEGIN-only: use AWK as a calculator
awk 'BEGIN { print 2^10 }' # -> 1024
# Count occurrences of each value in column 1, report in END
awk '{ count[$1]++ }
END { for (k in count) print k, count[k] }' access.logYou can have multiple BEGIN and multiple END blocks in one program; AWK runs all BEGIN blocks in order before input and all END blocks in order after input. They are effectively concatenated, which helps when composing scripts from includes.
Do not reference fields like $1 or $2 inside a BEGIN block expecting input data — no record has been read, so they are empty. Similarly, computing total/NR in END fails with a division error if NR is zero because the input was empty; guard with NR>0 when averaging.
- AWK runs BEGIN once before input, main rules per record, and END once after input.
- BEGIN is for setup: setting FS/OFS/RS/ORS, printing headers, seeding variables.
- In BEGIN, fields and FILENAME are empty because no record has been read yet.
- END sees final state: NR is the total record count and $0 is usually the last record.
- The accumulate-in-main, report-in-END pattern keeps per-record logic clean.
- A BEGIN-only program never reads input, useful as a calculator or formatter.
- Multiple BEGIN and END blocks are allowed and run in source order.
Practice what you learned
1. When does the BEGIN block execute?
2. What is a reliable value of NR inside the END block?
3. Why are $1 and $2 empty inside a BEGIN block?
4. What does the program awk 'BEGIN{print 2^10}' do?
5. How does AWK handle multiple END blocks?
Was this page helpful?
You May Also Like
Built-in Variables in AWK
AWK ships with a set of predefined variables such as NR, NF, FS, and OFS that expose the current record, field counts, and formatting controls without any setup.
User-Defined Variables in AWK
Beyond built-ins, AWK lets you create your own scalar and associative-array variables with dynamic typing and automatic initialization, powering counters, accumulators, and lookups.
Field Separators and Record Separators
FS and RS govern how AWK splits input into fields and records, while OFS and ORS control how output is reassembled; mastering them unlocks CSV, multiline, and custom-delimited parsing.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics