awk BEGIN and END: Setup and Summary Blocks
awk BEGIN runs once before the first line and END runs once after the last, framing the per-line work in between.
BEGIN sets separators and prints a header; END prints a total or average. Between them, the main block runs per line. This structure is the backbone of awk reports.
What it does
The BEGIN block executes before any input is read, so it is where you set FS, OFS, or print a header. The END block executes after all input, with NR, accumulators, and arrays fully populated, so it is where totals and averages go.
Common usage
# header in BEGIN, total in END
awk 'BEGIN{print "file size"} {sum+=$1} END{print "total", sum}' sizes.txt
# set separators up front
awk 'BEGIN{FS=","; OFS="\t"} {print $1, $2}' data.csv
# BEGIN-only: no input needed
awk 'BEGIN{print "hello from awk"}'Blocks
| Block | When it runs |
|---|---|
| BEGIN{...} | Once, before the first line is read |
| {...} | Once per input line |
| END{...} | Once, after the last line is read |
| BEGIN{FS=","} | Common: set the field separator before reading |
| END{print NR} | Common: print the line count after all input |
In CI
A BEGIN-only program (awk 'BEGIN{...}') runs without any input file, useful for arithmetic or formatting in a step. Accumulate in the main block and report in END so a single awk pass produces both filtered lines and a summary.
Common errors in CI
"awk: cmd. line:1: ... unexpected newline or end of string" usually means an unclosed brace in BEGIN or END. Putting END logic in the main block prints a running total on every line instead of one final total. Referring to a per-line field like $1 inside END gives the last line read, not a sum, so accumulate into a variable during the main block.