awk Patterns
awk patterns I’ve actually used. Every entry has a date and context.
2026-03-05: PEM Certificate Chain Split
Problem: Need to extract individual certs from a chain file
Context: ISE certificate deployment, splitting chain.pem into leaf/issuing/root
The Fix:
# Extract first cert (leaf)
awk '/-----BEGIN CERTIFICATE-----/{n++} n==1' chain.pem > leaf.pem
# Extract second cert (issuing CA)
awk '/-----BEGIN CERTIFICATE-----/{n++} n==2' chain.pem > issuing-ca.pem
# Extract third cert (root CA)
awk '/-----BEGIN CERTIFICATE-----/{n++} n==3' chain.pem > root-ca.pem
How it works: Counter n increments each time BEGIN CERTIFICATE is seen. n==1 prints only while counter equals 1 (first cert block).
Worklog: WRKLOG-2026-03-05
2026-03-05: Field Separator for Dots
Problem: Split IP address or FQDN by dots
Context: Network diagnostics, parsing ip command output
The Fix:
# WRONG: dot is regex "any char"
awk -F'.' '{print $1}' file
# RIGHT: escape the dot
awk -F'\\.' '{print $1}' file
# ALSO RIGHT: use bracket (more readable)
awk -F'[.]' '{print $1}' file
Rule: -F takes a regex. Dots must be escaped or bracketed.
Worklog: WRKLOG-2026-03-05
2026-03-05: Pipe Field Separator
Problem: Parse pipe-delimited output
Context: Parsing switch/router show commands
The Fix:
# WRONG: pipe is regex alternation
awk -F'|' '{print $1}' file
# RIGHT: escape or bracket
awk -F'\\|' '{print $1}' file
awk -F'[|]' '{print $1}' file
Worklog: WRKLOG-2026-03-05
2026-03-01: Line Range with Buffer
Problem: Show first 5 and last 5 lines of a file with line numbers
Context: Quick file inspection without loading entire file
The Fix:
awk 'NR<=5 {print NR": "$0; next} {buf[NR]=$0} END {print "..."; for(i=NR-4;i<=NR;i++) print i": "buf[i]}' file
How it works: - First 5 lines: print immediately with line number - Remaining lines: store in buffer array (overwrites, keeping only recent) - END: print last 5 from buffer
Worklog: WRKLOG-2026-03-01
2026-03-05: Extract IP from Command Output
Problem: Get IP address from ip addr output
Context: Network diagnostics, scripting
The Fix:
# Get IP with CIDR
ip -4 addr show eth0 | awk '/inet/{print $2}'
# Get just IP without CIDR
ip -4 addr show eth0 | awk '/inet/{split($2,a,"/"); print a[1]}'
# Get default route interface
ip route | awk '/default/{print $5}'
Worklog: WRKLOG-2026-03-05
2026-04-05: find + awk — Filter vs Find-Native
Problem: Filter find output by filename pattern using awk
Context: Searching for CLAUDE.md in dots-quantum repo during opencode config audit. Hand-typed all variants to build muscle memory.
The Fix:
# WORKS but wasteful — awk filters what find already knows
find . -type f -name "*.md" | awk '/CLAUDE/'
# RIGHT — push filter into find
find . -type f -name "CLAUDE.md"
# ALSO RIGHT — partial match on filename
find . -type f -name "*CLAUDE*.md"
# RIGHT — when filtering on path components
find . -type f -path "*CLAUDE*" -name "*.md"
# WHEN awk IS right — filtering on CONTENT, not filename
find . -type f -name "*.md" -exec awk '/^## Role:/{print FILENAME": "$0}' {} +
Rule: If awk is only doing // (pattern match) on filenames, push that into find -name or -path. Reserve find -exec awk for content filtering or field extraction — that’s where the combination actually earns its complexity.
Worklog: WRKLOG-2026-04-05