
BEGIN{ 预处理 }
# 逐行处理文本
pattern{ action }
END{ 收尾汇总 }$0:整行文本;$1/$2/$n:第1/2/n列NF:当前行总列数;NR:当前行号;FNR:多文件各自行号FS:输入分隔符;OFS:输出分隔符;RS:行分隔符;ORS:输出行分隔符# -F 指定分隔符,冒号分割 /etc/passwd
awk -F: '{print $1,$7}' /etc/passwd
# OFS 修改输出分隔符为 |
awk -F: 'BEGIN{OFS="|"}{print $1,$3}' /etc/passwd# 分隔符:空格、逗号、横杠 任意一个
awk -F '[ ,-]' '{print $1,$2}' test.txt
# 连续多个分隔符视为一个
awk -F '[: ]+' '{print $1}' test.txt# 前10行逗号分割,10行后空格分割
awk 'NR<=10{FS=","}NR>10{FS=" "}{print $1}' test.txt# 空行分隔段落,按段落处理文本
awk -v RS="" '{print "段落:"$0}' test.txt
# 以###作为行结束符
awk -v RS="###" '{print $0}' test.txt# 第三列大于100
awk '$3 > 100' test.txt
# 第2列等于字符串
awk '$2 == "error"' log.txt
# 不等于、小于等于
awk '$4 != 0 && $5 <= 50' test.txt# 包含ERROR的行
awk '/ERROR/' app.log
# 第5列匹配数字
awk '$5 ~ /^[0-9]+$/' test.txt
# 不包含timeout
awk '! /timeout/' nacos.log
# 忽略大小写匹配
awk 'BEGIN{IGNORECASE=1}/grpc/' log.txt# 第10~100行
awk 'NR>=10 && NR<=100' test.txt
# 匹配start到end之间所有行
awk '/start/,/end/' log.txt# 包含ERROR 且 第6列超时大于3000
awk '/ERROR/ && $7>3000' nacos.log
# 包含Timeout 或者 Connection
awk '/Timeout/ || /Connection/' app.logawk '{
if($3 > 1000){
print $1,"高负载"
}else if($3>500){
print $1,"中等负载"
}else{
print $1,"正常"
}
}' test.txt# 打印每行所有字段
awk '{for(i=1;i<=NF;i++) print $i}' test.txt
# 遍历数组key
awk '{arr[$1]=$2}END{for(k in arr) print k,arr[k]}' test.txt# 循环输出每行前3列
awk '{i=1;while(i<=3){print $i;i++}}' test.txt# next:跳过当前行,直接处理下一行
awk '$1=="skip"{next}{print $0}' test.txt
# break 跳出循环
awk '{for(i=1;i<=NF;i++) if($i=="end") break; print $i}' test.txt
# exit 直接结束程序(END仍会执行)
awk 'NR>100{exit}' test.txtawk 数组是关联数组,key可以数字/字符串,核心用于日志统计。
# 统计每个IP出现ERROR次数
awk '/ERROR/ && $9~/172.18/{ip=$9; cnt[ip]++}END{for(ip in cnt) print ip,cnt[ip]}' nacos.log# 提取不重复的IP
awk '{ip[$9]=1}END{for(i in ip) print i}' log.txt# 统计第三列总和、平均值
awk '{sum+=$3; num++}END{print "总和="sum,"平均="sum/num}' test.txt
# 求最大值
awk '{if($3>max) max=$3}END{print "最大值:"max}' test.txt# key:ip+status 分组统计
awk '{key=$9"_"$7; arr[key]++}END{for(k in arr) print k,arr[k]}' log.txtawk '{arr[$1]=$2}END{delete arr["127.0.0.1"];for(k in arr)print k}' test.txtawk 'BEGIN{
FS=":";OFS="\t"
print "用户名","UID","Shell"
}{print $1,$3,$7}' /etc/passwd# 统计日志等级数量
awk '/ERROR|WARN|INFO/{level=$1;count[level]++}END{
print "日志统计:"
print "ERROR:",count["ERROR"]+0
print "WARN:",count["WARN"]+0
print "INFO:",count["INFO"]+0
}' app.log# -v 传外部shell变量到awk
search="Timeout"
awk -v key="$search" '$0 ~ key' nacos.log
# 传递数字
threshold=3000
awk -v t="$threshold" '$7 > t' log.txt比print更灵活,支持对齐、数字格式化:
# %s字符串 %d整数 %f浮点数 左对齐- 宽度10
awk '{printf "IP:%-15s 耗时:%6d ms\n",$9,$7}' nacos.log
# 保留2位小数
awk '{printf "平均值:%.2f\n",$3/1000}' test.txt
# 十六进制输出
awk '{printf "UID 十六进制:%x\n",$3}' /etc/passwdfile1:ip name
file2:ip cost
# 先缓存第一个文件,第二个文件匹配输出
awk 'NR==FNR{map[$1]=$2;next}{print $1,map[$1],$2}' file1 file2awk '{file[FILENAME]++}END{for(f in file) print f,file[f]}' a.txt b.txtawk 'FILENAME=="passwd"{print $1}FILENAME=="group"{print $2}' /etc/passwd /etc/grouplength($0) | |
sub(/old/,new,$0) | |
gsub(/old/,new,$0) | |
index(s,t) | |
substr(s,start,len) | |
split(s,arr,sep) | |
tolower() / toupper() |
示例:
# 全局替换端口9848为9849
awk '{gsub("9848","9849");print $0}' nacos.log
# 截取IP前3段
awk '{ip=substr($9,1,index($9,".")+3);print ip}' log.txt
# 分割字符串
echo "172.18.2.184" | awk '{split($0,arr,".");print arr[1],arr[2]}'int(x) # 取整
sqrt(x) # 开平方
rand() # 0~1随机数
srand() # 设置随机种子
log() exp() sin() cos()# 时间戳转日期
awk 'BEGIN{print strftime("%Y-%m-%d %H:%M:%S",systime())}'
# 格式化日志时间
awk '{t=$1" "$2;print strftime("%H:%M",mktime("2026 "t))}' log.txt()# 提取172.18开头IP
awk 'match($0,/(172\.18\.[0-9]+\.[0-9]+)/,arr){print arr[1]}' nacos.logmatch() 函数捕获正则分组到数组. * + ? | () 需加反斜杠 \.# 统计3000ms以上超时IP及次数
awk '/TimeoutException/ && match($0,/172\.18\.[0-9.]+/,ip){
cnt[ip[0]]++
}END{
printf "%-15s %s\n","IP","超时次数"
for(k in cnt) printf "%-15s %d\n",k,cnt[k]
}' nacos-raft.logawk '"Thread" in $0{name=$0;next}/WAITING|BLOCKED/{arr[name]++}END{for(t in arr) print arr[t],t}' jstack.logawk 'BEGIN{OFS=" | "}
/ERROR/{
gsub(/[0-9]{2}:[0-9]{2}:[0-9]{2}/,"TIME",$0)
print $1,$2,$9,$NF
}' app.log > error-filter.logdf -h | awk 'NR>1{gsub(/G/,"",$3);sum+=$3}END{print "总使用G:",sum}'awk '{ip=$1;visits[ip]++}END{
print "访问TOP10:"
for(i in visits) print visits[i],i
}' access.log | sort -nr | head -10awk '{lines[$1] = lines[$1] " " $0}END{for(k in lines) print k,lines[k]}' log.txtawk 'NR==FNR{map[$1]=$2;next}{...}' f1 f2gsub 频繁全局替换,能用match就不用gsub== 字符串相等、= 赋值,写条件不要写错$NF 最后一列;$(NF-1) 倒数第二列arr[key]+0 防止空输出# 打印最后一列
awk '{print $NF}'
# 打印倒数第二列
awk '{print $(NF-1)}'
# 打印行号+内容
awk '{print NR,$0}'
# 过滤空行
awk 'NF>0'
# 删除重复行(保留首次出现)
awk '!seen[$0]++'
# 统计总行数
awk 'END{print NR}'
# 字段包含数字
awk '$1 ~ /[0-9]/'
# 输出不重复字段
awk '{u[$1]}END{for(i in u)print i}'