100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

AWK Scripting for Report Generation

Using AWK's BEGIN/END blocks, printf formatting, and associative arrays to turn raw tabular data into clean, aligned, human-readable reports.

Practical AWKIntermediate10 min readJul 10, 2026
Analogies

The Report Skeleton: BEGIN, Body, END

A well-structured AWK report has three parts. The BEGIN block runs once before any input and is where you print headers, set OFS, and initialize totals. The main body runs per record to accumulate data into variables and associative arrays. The END block runs once after all input and is where you print the aggregated results and footer totals. This three-phase shape mirrors a printed report's header, table, and summary line, and separating them keeps the logic clean: gather in the body, present in END.

🏏

Cricket analogy: The structure is like a match broadcast: BEGIN is the pre-match presentation setting the scene, the body is ball-by-ball commentary accumulating the score, and END is the post-match summary with the final scorecard.

Formatting Columns with printf

The print statement is fine for quick output but crude for reports because it cannot control width or alignment. printf gives you C-style format specifiers: %-20s left-justifies a string in 20 columns, %10.2f right-justifies a float in 10 columns with two decimals, and %5d pads an integer. A typical report line is printf "%-20s %10.2f %8d\n", name, amount, qty. Unlike print, printf does not add a newline automatically, so you must include \n yourself. Consistent format strings for the header and body rows are what make columns line up into a readable table.

🏏

Cricket analogy: printf is like a properly ruled scorecard where each column has a fixed width for runs, balls, and strike rate, unlike scribbling figures that never line up under the headings.

awk
# sales.txt columns: region  product  amount
# Report: total amount per region, aligned, with grand total
awk '
BEGIN {
    printf "%-12s %12s\n", "REGION", "TOTAL"
    printf "%-12s %12s\n", "------", "-----"
}
{
    total[$1] += $3
    grand += $3
}
END {
    for (r in total)
        printf "%-12s %12.2f\n", r, total[r]
    printf "%-12s %12s\n", "------", "-----"
    printf "%-12s %12.2f\n", "GRAND", grand
}
' sales.txt

Grouped Subtotals and Sorted Output

Reports usually need grouping and often a stable sort order. Associative arrays give the grouping: total[$1] += $3 accumulates a subtotal per key. AWK's array iteration order is unspecified, so to present rows sorted you either pipe the END output through sort, or in GNU AWK call asorti(total, keys) to sort the keys into an indexed array and iterate that. For running subtotals within a sorted input, track the current group in a variable and, when the key changes, flush the subtotal before resetting, a classic control-break report pattern.

🏏

Cricket analogy: Grouped subtotals are like partnership totals in an innings: you keep a running stand for the current pair and, when a wicket falls, you record that partnership before the next pair begins.

In GNU AWK (gawk), asort() sorts array values and asorti() sorts array indices into a new array, giving you deterministic report ordering without an external sort. In POSIX AWK there is no built-in sort, so piping the END output to the sort command is the portable choice.

Never assume for (k in arr) iterates in insertion or sorted order — AWK's traversal order is implementation-defined and effectively random. If your report needs a stable order, sort explicitly with asorti() or an external sort; relying on hash order produces reports that reshuffle unpredictably.

  • Structure reports as BEGIN (headers/init), body (accumulate), END (present totals).
  • Use printf, not print, for width and alignment; remember to add \n yourself.
  • Format specifiers: %-Ns left-justify strings, %N.2f right-justify floats, %Nd pad integers.
  • Associative arrays produce grouped subtotals keyed by any field.
  • Array iteration order is unspecified; sort keys with asorti() (gawk) or pipe to sort.
  • Control-break reporting flushes a subtotal when the sorted group key changes.
  • Maintain a grand-total variable across the body and print it in END as the footer.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#AWKStudyNotes#AWKScriptingForReportGeneration#AWK#Scripting#Report#Generation#StudyNotes#SkillVeris#ExamPrep