news 2026/3/14 4:52:32

awk用法与技巧详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
awk用法与技巧详解

一、awk基本概念

1.1 什么是awk

awk是一种强大的文本分析工具,用于对文本文件进行逐行处理。它支持模式匹配、数据提取、计算和格式化输出等功能。

1.2 基本语法

支持下面3种写法

awk 'pattern {action}' input_file awk -f script.awk input_file script.awk input_file # 需要在script.awk第一行写“#!/bin/awk -f”,并赋予文件可执行权限chmod +xscript.awk

二、awk工作原理

2.1 执行流程

  1. 读取输入文件的一行

  2. 按字段分隔符分割成字段

  3. 检查是否匹配pattern

  4. 如果匹配,执行action

  5. 重复直到文件结束

2.2 内置变量

变量说明示例
$0整行内容{print $0}
$1, $2...第1,2...个字段{print $1}
NF当前行的字段数{print NF}
NR当前行号{print NR}
FNR当前文件的行号{print FNR}
FS输入字段分隔符-F: 或 BEGIN{FS=":"}
OFS输出字段分隔符BEGIN{OFS="\t"}
RS输入记录分隔符BEGIN{RS="\n"}
ORS输出记录分隔符BEGIN{ORS="\n\n"}
FILENAME当前文件名{print FILENAME}

三、常用用法示例

3.1 基本打印

# 打印整行 awk '{print}' file.txt awk '{print $0}' file.txt # 打印第一列 awk '{print $1}' file.txt # 打印多列 awk '{print $1, $3, $5}' file.txt # 打印最后一列 awk '{print $NF}' file.txt # 打印倒数第二列 awk '{print $(NF-1)}' file.txt

3.2 指定分隔符

# 指定输入分隔符 awk -F: '{print $1}' /etc/passwd awk 'BEGIN{FS=":"} {print $1}' /etc/passwd # 同时指定输入输出分隔符 awk -F: 'BEGIN{OFS="\t"} {print $1, $3}' /etc/passwd # 多个分隔符 awk -F'[:,]' '{print $1, $2}' file.txt

3.3 条件筛选

# 匹配包含"error"的行 awk '/error/' log.txt # 第三列等于"GET" awk '$3 == "GET"' access.log # 数值比较 awk '$4 > 100' data.txt awk '$4 >= 100 && $4 <= 200' data.txt # 第一列匹配正则 awk '$1 ~ /^192\.168/' log.txt # 取反匹配 awk '!/error/' log.txt awk '$1 !~ /^192\.168/' log.txt

3.4 BEGIN和END模式

# 在开始前执行 awk 'BEGIN{print "开始处理"} {print $0}' file.txt # 在结束后执行 awk '{sum+=$1} END{print "总和:", sum}' numbers.txt # 结合使用 awk 'BEGIN{FS=":"; OFS="\t"; print "用户名\tUID"} {print $1, $3} END{print "处理完成"}' /etc/passwd

四、高级用法与技巧

4.1 计算与统计

# 求和 awk '{sum+=$1} END{print sum}' numbers.txt # 平均值 awk '{sum+=$1; count++} END{print "平均:", sum/count}' numbers.txt # 最大值 awk 'NR==1{max=$1} $1>max{max=$1} END{print "最大值:", max}' numbers.txt # 最小值 awk 'NR==1{min=$1} $1<min{min=$1} END{print "最小值:", min}' numbers.txt # 统计行数 awk 'END{print NR}' file.txt

4.2 数组操作

# 统计词频 awk '{for(i=1;i<=NF;i++) count[$i]++} END{for(word in count) print word, count[word]}' text.txt # 按第一列分组求和 awk '{sum[$1]+=$2} END{for(key in sum) print key, sum[key]}' data.txt # 去重 awk '!seen[$0]++' file.txt # 去重整行 awk '!seen[$1]++' file.txt # 按第一列去重

4.3 字符串处理

# 字符串连接 awk '{print $1 "-" $2}' file.txt # 字符串长度 awk '{print length($1)}' file.txt # 子字符串 awk '{print substr($1, 2, 4)}' file.txt # 从第2个字符开始取4个 # 字符串替换 awk '{gsub(/old/, "new"); print}' file.txt awk '{gsub(/old/, "new", $1); print $1}' file.txt # 匹配位置 awk '{print index($0, "target")}' file.txt

4.4 流程控制

# if语句 awk '{if($1>100) print $0}' data.txt awk '{if($1>100) print "大"; else if($1>50) print "中"; else print "小"}' data.txt # 三元运算符 awk '{print ($1>100 ? "高" : "低")}' data.txt # for循环 awk '{for(i=1;i<=NF;i++) print i, $i}' file.txt awk 'BEGIN{for(i=1;i<=5;i++) print i}' # while循环 awk '{i=1; while(i<=NF){print $i; i++}}' file.txt

五、实用技巧集合

5.1 日志分析

# 统计HTTP状态码 awk '{status[$9]++} END{for(s in status) print s, status[s]}' access.log # 统计IP访问量 awk '{ip[$1]++} END{for(i in ip) print i, ip[i]}' access.log | sort -k2 -nr # 提取时间段的日志 awk '/12\/Dec\/2023:10:/,/12\/Dec\/2023:11:/' access.log # 统计接口响应时间大于1秒的请求 awk '$NF > 1 {print $7, $NF}' access.log | sort -k2 -nr

5.2 数据格式化

# 对齐输出 awk '{printf "%-20s %10d\n", $1, $2}' data.txt # 生成表格 awk 'BEGIN{printf "+----------------+----------+\n| 名称 | 数值 |\n+----------------+----------+"} {printf "| %-14s | %8d |\n", $1, $2} END{printf "+----------------+----------+\n"}' data.txt # CSV转TSV awk 'BEGIN{FS=","; OFS="\t"} {$1=$1; print}' data.csv

5.3 系统管理

# 监控进程内存 ps aux | awk '$6>100000 {print $0}' # 磁盘使用率 df -h | awk 'NR>1 && $5+0 > 80 {print "警告:", $1, "使用率:", $5}' # 统计文件大小 ls -l | awk 'NR>1 {sum+=$5; count++} END{print "总数:", count, "总大小:", sum/1024/1024 "MB"}'

5.4 文本处理

# 提取两个标记之间的内容 awk '/START/,/END/' file.txt # 删除空行 awk 'NF' file.txt # 或 awk '!/^$/' # 添加行号 awk '{print NR, $0}' file.txt # 反转行序 awk '{lines[NR]=$0} END{for(i=NR;i>0;i--) print lines[i]}' file.txt # 合并连续空行为一个 awk 'NF{print; blank=0} !NF{blank++; if(blank==1) print}'

六、实战示例

6.1 分析Nginx访问日志

#!/bin/bash # 分析日志脚本 LOG_FILE="access.log" echo "=== 访问日志分析报告 ===" echo "1. 总访问次数:" awk 'END{print NR}' $LOG_FILE echo -e "\n2. 独立IP数量:" awk '{ip[$1]++} END{print length(ip)}' $LOG_FILE echo -e "\n3. 最活跃的10个IP:" awk '{ip[$1]++} END{for(i in ip) print ip[i], i}' $LOG_FILE | sort -nr | head -10 echo -e "\n4. HTTP状态码统计:" awk '{status[$9]++} END{for(s in status) printf "%-4s: %d\n", s, status[s]}' $LOG_FILE echo -e "\n5. 最受欢迎的10个页面:" awk '{page[$7]++} END{for(p in page) print page[p], p}' $LOG_FILE | sort -nr | head -10

6.2 数据报表生成

#!/usr/bin/awk -f # sales_report.awk - 销售报表生成 BEGIN { FS="," OFS="\t" print "销售报表" print "==========================================" print "销售人员\t销售额\t提成\t总工资" print "------------------------------------------" total_sales = 0 total_commission = 0 total_salary = 0 } { sales = $2 commission = sales * 0.1 # 10%提成 salary = 3000 + commission total_sales += sales total_commission += commission total_salary += salary printf "%s\t%.2f\t%.2f\t%.2f\n", $1, sales, commission, salary } END { print "------------------------------------------" printf "总计\t%.2f\t%.2f\t%.2f\n", total_sales, total_commission, total_salary print "==========================================" }

七、性能优化技巧

预处理模式匹配

# 差的写法 awk '{if($1=="A" || $1=="B" || $1=="C") print}' # 好的写法 awk '$1=="A" || $1=="B" || $1=="C"' awk '$1 ~ /^(A|B|C)$/'

减少字段引用

# 差的写法 awk '{print $1, $3, $5, $7, $9}' # 好的写法 awk '{printf "%s %s %s %s %s\n", $1, $3, $5, $7, $9}'

使用内置函数代替shell命令

# 避免调用外部命令 awk '{system("echo " $1)}' # 慢 awk '{print $1}' # 快

八、常见问题解答

Q1: awk与sed的区别?

  • awk:更适合处理结构化数据,支持字段操作、计算、数组

  • sed:更适合简单的文本替换、删除、插入

Q2: 如何处理大文件?

  • 使用合适的字段分隔符

  • 避免在action中调用外部命令

  • 使用next跳过不相关的行

Q3: awk可以处理二进制文件吗?

  • 不推荐,awk是文本处理工具,对于二进制文件应使用专门的工具

九、学习资源

  1. 官方文档:man awk,info awk

  2. 经典书籍: 《sed与awk》

  3. 在线练习: 使用小文件进行测试

  4. 实践项目: 分析系统日志、处理CSV数据、生成报表

通过掌握这些用法和技巧,你可以高效地使用awk处理各种文本分析任务,大大提高工作效率。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/6 10:54:18

上位机软件串口调试:手把手教你定位通信瓶颈

上位机软件串口调试&#xff1a;从“卡顿”到流畅&#xff0c;我如何揪出通信链路中的隐藏瓶颈&#xff1f;你有没有遇到过这样的场景&#xff1a;一台温湿度传感器每秒上报一次数据&#xff0c;明明波特率设的是115200&#xff0c;理论上完全够用——可你的上位机软件却像卡顿…

作者头像 李华
网站建设 2026/3/10 9:27:31

终极Unity游戏翻译方案:3步实现多语言无障碍体验

终极Unity游戏翻译方案&#xff1a;3步实现多语言无障碍体验 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 还在为外语游戏中的对话一头雾水而烦恼吗&#xff1f;是否曾经因为语言障碍而错过了精彩的剧情…

作者头像 李华
网站建设 2026/3/4 3:09:12

百度网盘提取码一键查询终极指南:告别繁琐搜索的智能解决方案

百度网盘提取码一键查询终极指南&#xff1a;告别繁琐搜索的智能解决方案 【免费下载链接】baidupankey 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 还在为百度网盘分享链接的提取码而四处寻找吗&#xff1f;面对加密分享和隐藏密码&#xff0c;传统的人…

作者头像 李华
网站建设 2026/3/11 7:40:56

百度网盘提取码智能获取:5分钟快速上手指南

百度网盘提取码智能获取&#xff1a;5分钟快速上手指南 【免费下载链接】baidupankey 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 还在为百度网盘分享链接的提取码而烦恼吗&#xff1f;面对加密分享和隐藏密码&#xff0c;传统的人工查找方式既费时又低…

作者头像 李华
网站建设 2026/3/5 13:50:43

YOLOv8预训练权重下载慢?HuggingFace镜像网站加速方案推荐

YOLOv8预训练权重下载慢&#xff1f;HuggingFace镜像网站加速方案推荐 在实际项目开发中&#xff0c;你是否也遇到过这样的场景&#xff1a;刚搭建好环境&#xff0c;兴冲冲地准备跑一个YOLOv8目标检测Demo&#xff0c;结果执行 model YOLO("yolov8n.pt") 时卡在了模…

作者头像 李华
网站建设 2026/3/11 2:49:54

导师推荐8个AI论文平台,助你轻松搞定继续教育毕业论文!

导师推荐8个AI论文平台&#xff0c;助你轻松搞定继续教育毕业论文&#xff01; AI 工具如何助力论文写作&#xff0c;让学术之路更轻松 在继续教育的道路上&#xff0c;撰写毕业论文往往是许多学员面临的挑战之一。随着人工智能技术的不断进步&#xff0c;AI 工具逐渐成为解决这…

作者头像 李华