awk — Numeric Comparison
WRONG — string comparison makes "10" less than "9"
printf '%s\n' 3 7 10 15 2 9 | \
awk '$1 > 9'
# Prints nothing — "10" < "9" lexicographically ("1" < "9")
printf '%s\n' 3 7 10 15 2 9 | \
awk '$1+0 > 9'
# CORRECT — +0 forces numeric: prints 10, 15
Assignment vs comparison — = vs ==
cat <<'EOF' > /tmp/demo.txt
VLAN10 data active
VLAN20 voice active
VLAN99 quarantine inactive
EOF
# WRONG — assigns "active" to $3, always true, prints every line mangled
awk '$3 = "active"' /tmp/demo.txt
# CORRECT — tests equality
awk '$3 == "active"' /tmp/demo.txt
Check field exists before accessing
# /etc/passwd has 7 colon-delimited fields — safe to access $7
awk -F: 'NF >= 7 {print $1, $7}' /etc/passwd | head -5
# Without the guard, files with fewer fields silently return ""
Modifying $0 recalculates fields — but $1 is stale after gsub
echo 'old-vlan old-gateway old-dns' | \
awk '{gsub(/old/, "new"); print $0}'
# Output: new-vlan new-gateway new-dns
Uninitialized variables are 0 (numeric) or "" (string)
# count[$1] starts at 0, ++ makes it 1 on first hit
printf '%s\n' ERROR WARN ERROR INFO ERROR WARN | \
awk '{count[$1]++} END{for(k in count) print count[k], k}'
Associative array order is NOT guaranteed
# WRONG — relies on insertion order
printf '%s\n' ssh dns kerberos ssh dns ssh | \
awk '{a[$1]++} END{for(k in a) print k}'
# CORRECT — pipe to sort for deterministic output
printf '%s\n' ssh dns kerberos ssh dns ssh | \
awk '{a[$1]++} END{for(k in a) print k, a[k]}' | sort