AWK Advanced Patterns
Advanced AWK patterns for complex data processing.
Data Structures
awk '{a[NR%10]=$0} END {for(i=NR+1;i⇐NR+10;i++) print a[i%10]}' file
awk -v n=35 '{a[NR%n]=$0} END {for(i=NR+1;i⇐NR+n;i++) print a[i%n]}' file
awk '{freq[$1]++} END {for(k in freq) print freq[k], k}' file | sort -rn
awk '{freq[$1]++} END {for(k in freq) print freq[k], k}' file | sort -rn | head -10
awk '!seen[$0]++' file
awk 'NR==FNR {sum+=$1; next} {print $0, $1/sum*100"%"}' file file
Process Info
ps aux --sort=-%cpu | awk 'NR⇐11 {print $3, $11}'
ps aux --sort=-%mem | awk 'NR⇐11 {printf "%5.1f%% %s\n", $4, $11}'
for p in /proc/[0-9]*; do echo "$(ls $p/fd 2>/dev/null | wc -l) $(cat $p/comm 2>/dev/null)"; done | sort -rn | head -10
awk '/MemTotal|MemFree|MemAvailable|Buffers|Cached/ {printf "%-15s %8.2f GB\n", $1, $2/1024/1024}' /proc/meminfo
awk '{d=int($1/86400); h=int(($1%86400)/3600); m=int(($1%3600)/60); printf "%dd %dh %dm\n",d,h,m}' /proc/uptime
awk '{cores=0; while((getline line < "/proc/cpuinfo")>0) if(line~/^processor/) cores++; close("/proc/cpuinfo"); printf "Load: %s %s %s (cores: %d)\n",$1,$2,$3,cores}' /proc/loadavg
User Management
awk -F: '$3>=1000 && $3<65534 {print $1, $3, $7}' /etc/passwd
awk -F: '$7~/bash/ {print $1}' /etc/passwd
awk -F: '$7~/nologin|false/ {print $1}' /etc/passwd
awk -F: '/^wheel:/ {print $4}' /etc/group
awk -F: '$4!="" {print $1": "$4}' /etc/group
awk -F: '{n=split($4,a,","); if(n>0) print $1, n}' /etc/group | sort -k2 -rn
getent passwd | awk -F: '$3>=1000 && $3<65534 {print $1, $6}'
id username | awk -F'[=,()]' '{for(i=1;i⇐NF;i+) if($i~/^[0-9]$/ && $(i+1)!="") print $(i+1)}'
groups username | awk -F': ' '{print $2}' | tr ' ' '\n'
sudo awk -F: '{if($3!="") print $1, $3}' /etc/shadow
sudo awk -F: '$5=="" || $5==99999 {print $1}' /etc/shadow
sudo awk -F: '$2~/^[!*]/ {print $1}' /etc/shadow
awk -F: '{shells[$7]++} END {for(s in shells) print shells[s], s}' /etc/passwd | sort -rn
awk -F: '{shells[$7]=shells[$7] ? shells[$7]", "$1 : $1} END {for(s in shells) print s":", shells[s]}' /etc/passwd
awk -F: '$6~/^\/home/ {print $6}' /etc/passwd | while read d; do [[ -d "$d" ]] && echo "$d"; done
awk -F: '$3>=1000 && $6~/^\/home/ {print $6}' /etc/passwd | xargs -I{} du -sh {} 2>/dev/null
Certificate Parsing
openssl x509 -enddate -noout -in cert.pem | awk -F= '{print $2}'
openssl x509 -enddate -noout -in cert.pem | awk -F= '{cmd="date -d \""$2"\" +%s"; cmd|getline exp; close(cmd); print intexp-systime(/86400), "days"}'
openssl x509 -subject -noout -in cert.pem | awk -F’CN ?= ?' '{print $2}' | awk -F',' '{print $1}'
openssl x509 -noout -ext subjectAltName -in cert.pem | awk -F’DNS:' '{for(i=2;i⇐NF;i++) {gsub(/,.*/,"",$i); print $i}}'
openssl crl2pkcs7 -nocrl -certfile chain.pem | openssl pkcs7 -print_certs -noout | awk '/subject=|issuer=/ {print}'
echo | openssl s_client -connect host:443 2>/dev/null | openssl x509 -noout -enddate | awk -F= '{print $2}'
for h in host1 host2 host3; do echo -n "$h: "; echo | openssl s_client -connect $h:443 2>/dev/null | openssl x509 -noout -enddate | awk -F= '{print $2}'; done
Multi-File Operations
awk '{print FILENAME, FNR, NR, $0}' file1 file2
awk 'FNR==1 {print "=== " FILENAME " ==="} {print FNR, $0}' file1 file2
awk 'NR==FNR {a[$1]=$2; next} {print $0, a[$1]}' lookup.txt data.txt
awk 'NR==FNR {a[$1]=$2; next} $1 in a {print $0, a[$1]}' file1 file2
awk 'NR==FNR {a[$1]=$2; next} {print $0, ($1 in a ? a[$1] : "NULL")}' file1 file2
awk 'NR==FNR {a[$0]; next} !($0 in a)' file2 file1
awk 'NR==FNR {a[$0]; next} $0 in a' file2 file1
awk 'NR==FNR {a[$0]=1; next} {if($0 in a) a[$0]=0; else print} END {for(k in a) if(a[k]) print k}' file1 file2
awk '{print FILENAME, $0}' file1 file2 | sort -k2
awk 'NR==FNR {a[FNR]=$0; max=FNR; next} {print a[FNR]; print}' file1 file2
awk 'FILENAME=="users.txt" {users} FILENAME=="logins.txt" {logins[$1]} END {for(u in users) print u, logins[u]+0}' users.txt logins.txt