Linux awk 超全详细教程 📅 2026/8/4 20:31:37 一、基础介绍定义awk是文本处理编程语言擅长按行、按列解析日志、配置文件是三剑客grep、sed、awk里最强大的数据筛选工具。核心定位分列处理、统计计算、格式化输出工作模式逐行扫描文件默认以空格/制表符分割字段。主流版本gawkGNU awkLinux默认、nawk、mawk。语法格式awk [选项] 条件{动作} 文件名 # 标准完整版 awk [OPTIONS] BEGIN{初始化} 匹配规则{执行主体} END{收尾统计} fileBEGIN{}读取文件之前执行只运行1次常用于定义变量、打印表头。{}主体逐行读取文本匹配成功就执行内部代码。END{}文件读取结束后执行1次用于汇总、求和、平均值。二、内置常用变量最常用字段变量列变量含义$0整行全部内容$1第1列$2第2列……$n第n列NF当前行总列数$NF代表最后一列$(NF-1)倒数第二列行变量变量含义NR全局行号多文件叠加计数FNR单个文件行号多文件重新从1计数FS输入分隔符默认空格等价-F参数OFS输出分隔符默认空格RS行分隔符默认换行ORS输出行分隔符默认换行三、常用命令选项-F 指定分隔符高频# 逗号分割取第1、3列 awk -F , {print $1,$3} test.txt # 多分隔符空格、:、/ 都作为分割 awk -F [: /] {print $1} test.txt-v 自定义外部变量awk -v num10 {print $1num} test.txt-f调用awk脚本文件awk -f test.awk test.txt四、基础实操示例简单打印列# 打印整行 awk {print $0} test.txt # 打印第2、最后一列 awk {print $2,$NF} test.txt # 打印行号内容 awk {print NR,$0} test.txt分隔符案例# /etc/passwd 以:分割打印用户名($1)和shell($7) awk -F : {print $1,$7} /etc/passwd行过滤条件筛选数值比较# 筛选第3列数值大于100的行 awk $3100 {print $0} test.txt # 行号小于10的行 awk NR10 test.txt字符串匹配~匹配、!~不匹配# 包含root的行 awk $0 ~ /root/ /etc/passwd # 第1列不是ftp的行 awk $1 !~ /ftp/ /etc/passwd # 精准匹配 awk $1root /etc/passwd多条件 ||# 第2列20 且 第3列100 awk $220 $3100 {print} test.txtBEGIN 与 END 用法# 打印表头内容结尾统计行数 awk BEGIN{print 姓名 账号 shell} -F : {print $1,$3,$7} END{print 一共,NR,个用户} /etc/passwd # 求和统计第2列总和 awk {sum$2} END{print 总和,sum} test.txt # 求平均值 awk {sum$2;count} END{print sum/count} test.txt五、格式化输出 printfprint简单换行printf精准排版语法和C语言一致# %s字符串 %d整数 %f浮点数 \t制表符 \n换行 awk -F : {printf 用户名:%-10s 编号:%d\n,$1,$3} /etc/passwd常用格式符%s字符串、%d整数、%.2f保留2位小数%-10s左对齐占10字符%10s右对齐六、awk 流程控制if/for/whileif 判断# 第3列大于10输出大否则输出小 awk {if($310) print $1,大;else print $1,小} test.txt # 多分支 awk { if($1root) print 管理员; else if($1ftp) print ftp用户; else print 普通用户 } /etc/passwdfor 循环# 遍历一行所有列打印每一列 awk {for(i1;iNF;i) print $i} test.txt七、数组awk 核心常用于去重、统计awk数组为关联数组哈希下标可以是字符串/数字# 统计日志中IP出现次数$1为IP awk {ip[$1]} END{for(i in ip) print i,ip[i]} access.log # 文本去重 awk !a[$0] test.txt八、高频生产实战案例案例1查看系统内存使用率free | awk /Mem/{print 使用率,$3/$2*100,%}案例2统计nginx访问IP频次并排序awk {ip[$1]} END{for(k in ip)print ip[k],k} access.log | sort -nr案例3筛选空行、删除空行# 打印非空行 awk NF0 test.txt # 空行计数 awk /^$/{n} END{print 空行数量,n} test.txt案例4筛选指定行区间# 第10~20行 awk NR10 NR20 test.txt案例5计算磁盘总占用df -h | awk /^\/dev/{sum$5} END{print sum}九、常用简写技巧awk 1 file等价awk {print $0}打印全部行awk 0 file不输出任何内容!a[$0]万能去重sum$n快速累加求和十、易错点总结分隔符含特殊字符* . 要用正则转义字符串比较必须用单个是赋值BEGIN 只在开头执行无法读取文件内容NR多文件持续累加FNR单文件重置为1。