terminal:scripting:awk
Table of Contents
awk
A tiny language for column/record processing. Pattern: pattern { action }
per line. Ubuntu ships mawk (fast, smaller feature set) :
sudo apt install gawk gets you the full GNU dialect (gensub,
strftime, mktime, asort, BEGINFILE).
Model
awk '{print $1}' # $0=whole line, $1..$NF=fields, NF=count awk 'NR==5' # NR=line number (bare pattern = print) awk -F: '{print $1}' /etc/passwd # field separator awk -F: -v OFS='|' '{print $1,$3}' # output separator
Built-ins: NR record#, NF field count, FS/OFS/RS/ORS,
FILENAME, $0, $1..$NF, $(NF-1) (second-to-last).
Patterns
awk '$3 > 100' # numeric compare awk '$1 ~ /foo/' # field matches regex (== !~ for not) awk '/start/,/end/' # range pattern awk 'NR>=10 && NR<=20' awk 'length($0) > 80' # long lines awk 'END{print}' # last line
BEGIN / END: headers, totals
awk 'BEGIN{FS=":"} {s+=$3} END{print "total:",s}' /etc/passwd ps aux | awk '{m+=$6} END{printf "%.1f MB\n", m/1024}' # total RSS
Associative arrays: the main feature
awk '{count[$1]++} END{for(k in count) print k, count[k]}' # histogram awk '{seen[$0]++} !seen[$0]-1' ... # just: awk '!seen[$0]++' dedupes awk '{sum[$1]+=$2} END{for(k in sum) print k":"sum[k]}' # group+sum
String functions
length(x) substr(s,i,n) index(s,t) tolower(s) toupper(s) split(s,a,sep) # array from string gsub(re,rep,str) # global replace IN the string (returns count) sub(re,rep,str) # first only sprintf(fmt,...) # returns formatted (printf prints) match(s,re) # sets RSTART/RLENGTH
awk '{gsub(/"/,""); print}' csvish.txt awk '{split($1,a,"."); print a[1]}' # first dotted part awk '{printf "%-20s %6.2f\n", $1, $2}' # aligned columns
Multiline / CSV-ish handling
awk -v RS='' '{print NR": "$0}' f # paragraph mode (blank-line records) awk -F'";"' '{print $2}' file # crude quoted-CSV: real CSV → miller
Recipes
ps aux | awk '$3>5 {print $2, $3, $11}' # processes >5% CPU df -h | awk 'NR>1 && $5+0>80 {print $6,$5}' # mounts over 80% awk '{s[$1]++} END{for(x in s) print s[x],x}' access.log | sort -rn | head awk 'NR==FNR{a[$1]=1;next} !($1 in a)' a.txt b.txt # lines in b not in a awk '{print $NF}' # last field seq 100 | awk '{sum+=$1} END{print sum/NR}' # mean
Gotchas
- Fields are 1-indexed,
$0is the whole line. -Ftakes a regex:-F'[,:]' splits on either.- String vs number:
$1 == “5”string compare,$1 == 5numeric. printadds ORS (newline);printfdoesn't.- mawk lacks
gensub/strftime: installgawkif a script needs them.
See Also
terminal/scripting/awk.txt · Last modified: by 127.0.0.1
