Arrays

Chapter 6
Arrays in AWK
Associative arrays, and the counting/grouping/deduplication patterns that make them genuinely powerful

This is the chapter where AWK stops feeling like a text filter and starts feeling like a real data-processing tool. AWK arrays are associative — indexed by arbitrary strings, not just sequential numbers — which makes them perfect for exactly the kind of "group by" and "count occurrences of" operations that come up constantly with real-world data.

Associative Arrays — The Basics

No declaration needed — an array springs into existence the first time you assign to any index of it.

$ awk 'BEGIN {
fruit["apple"] = 5
fruit["banana"] = 3
print fruit["apple"]
}'

5
fruit["apple"]5
fruit["banana"]3

Pattern 1 — Counting Occurrences

The single most common array pattern in all of AWK: count how many times each distinct value appears.

$ # Count how many log lines came from each status code
$ awk '{ counts[$9]++ } END { for (code in counts) print code, counts[code] }' access.log
200 1543
404 87
500 12

counts[$9]++ works even for a status code that's never been seen before — AWK treats an unset array index as 0 in a numeric context, so the first increment correctly produces 1. No explicit "if this key doesn't exist yet, initialise it" check is needed.

Pattern 2 — Grouping Values

Sometimes the goal isn't a count, but accumulating a running total or list per group — same fundamental pattern, different operation per match.

$ # Sum sales total per category (field 1 = category, field 3 = amount)
$ awk '{ totals[$1] += $3 } END { for (cat in totals) printf "%-10s %.2f\n", cat, totals[cat] }' sales.csv
books 245.50
electronics 1830.00

Pattern 3 — Deduplication

Using array keys as a "seen before" check is a clean, idiomatic way to print only unique values, without needing to sort first or compare against previous lines manually.

$ # Print each unique value in field 1 exactly once, first-seen order preserved
$ awk '!seen[$1]++' file.txt

This is a famously compact AWK idiom worth understanding fully: seen[$1]++ increments the count for this value and returns its previous value (0 the first time, then 1, 2...). !0 is true, so the first occurrence of any value passes the implicit pattern (and prints, per Chapter 1's "pattern with no action defaults to print"); every subsequent occurrence evaluates !1, !2, etc. — all false, so they're filtered out.

!seen[$1]++ is genuinely one of the most quoted AWK one-liners in existence
It accomplishes in a few characters what would otherwise need an explicit if/else and a separate counting step — exactly the kind of expressive compactness AWK is known for, once the underlying logic actually makes sense rather than being memorised as magic.

Iterating Over an Array — for...in

$ for (key in array) { print key, array[key] }
for...in does NOT guarantee any particular order
Unlike iterating over a numerically indexed list in most languages, AWK's for (key in array) visits keys in an implementation-defined order — not insertion order, not alphabetical, not numerical. If a specific output order matters (alphabetical, by count descending), pipe the AWK output into sort afterward rather than trying to control ordering inside AWK itself.
$ # Get counts, then sort the OUTPUT by count descending using the sort command
$ awk '{ counts[$9]++ } END { for (c in counts) print counts[c], c }' access.log | sort -rn

Checking Whether a Key Exists — Without Creating It

$ # The wrong way — this CREATES the key just by referencing it
$ if (arr["maybe"] == "") { ... }

$ # The correct way — (key in array) checks existence without creating it
$ if ("maybe" in arr) { print "exists" }
Simply referencing arr[key] creates that key as a side effect
This catches people out constantly: just checking arr["maybe"] in a condition (rather than using the dedicated in operator) silently creates an empty entry for "maybe" if it didn't already exist — which can quietly inflate a later for...in loop or array length count. Always use (key in array) for a genuine existence check.

Command Reference

SyntaxWhat it does
arr[key] = valueAssign a value, creating the key if it doesn't exist
arr[key]++Increment a counter, treating a missing key as 0
for (key in arr)Iterate over all keys, in unspecified order
(key in arr)Check existence WITHOUT creating the key as a side effect
delete arr[key]Remove a specific key from the array

Chapter 6 Quick Reference

  • Associative arrays — indexed by arbitrary strings, created on first assignment, no declaration needed
  • Counting: counts[key]++ — missing keys treated as 0 automatically
  • Grouping/totals: totals[key] += value, read in END
  • Deduplication: !seen[$1]++ — a compact, genuinely useful idiom once understood
  • for (key in arr) — order is NOT guaranteed; pipe to sort if order matters
  • (key in arr) — checks existence WITHOUT creating the key; referencing arr[key] directly DOES create it
  • Next chapter: control flow — if/else, for and while loops in AWK