awk 基本使用
awk 是一种强大的文本处理编程语言,特别适合处理结构化文本数据(如日志、CSV、表格数据等)。它以行为单位处理文本,并可以按字段进行操作。
基本语法结构
awk 'pattern { action }' file
或
command | awk 'pattern { action }'
- pattern:匹配模式(可选)
- action:执行的操作(用花括号
{}括起来) - file:要处理的文件
常用命令行选项
| 选项 | 说明 |
|---|---|
-F fs |
设置字段分隔符 |
-v var=value |
定义变量 |
-f scriptfile |
从文件读取 awk 脚本 |
-W |
启用特定扩展功能 |
核心概念
1. 字段和记录
- 记录 (Record):默认以换行符分隔,一行就是一个记录
- 字段 (Field):默认以空格或制表符分隔,每个单词是一个字段
- $0:整个当前行
- $1, $2, $3…:第 1、2、3…个字段
- NF:当前行的字段数量
- NR:当前处理的行号(从 1 开始)
常用内置变量
| 变量 | 说明 | 示例 |
|---|---|---|
$0 |
整行内容 | {print $0} |
$n |
第 n 个字段 | {print $1, $3} |
NF |
字段数量 | {print "字段数:", NF} |
NR |
当前行号 | {print "行号:", NR} |
FS |
输入字段分隔符 | BEGIN{FS=":"} |
OFS |
输出字段分隔符 | BEGIN{OFS="-"} |
RS |
输入记录分隔符 | |
ORS |
输出记录分隔符 |
基本用法示例
1. 打印整行
awk '{print $0}' file.txt # 打印所有行
awk '{print}' file.txt # 同上,print默认打印$0
2. 打印特定字段
awk '{print $1}' file.txt # 打印每行第1个字段
awk '{print $1, $3}' file.txt # 打印第1和第3个字段
awk '{print $NF}' file.txt # 打印最后一个字段
3. 设置字段分隔符
# 使用-F选项
awk -F':' '{print $1}' /etc/passwd
awk -F',' '{print $2}' data.csv
# 在BEGIN块中设置
awk 'BEGIN{FS=":"} {print $1}' file.txt
awk 'BEGIN{FS="[;,]"} {print $1}' file.txt # 多个分隔符
4. 条件筛选
# 打印包含"error"的行
awk '/error/ {print}' log.txt
# 打印不包含"error"的行
awk '!/error/ {print}' log.txt
# 第3个字段大于100的行
awk '$3 > 100 {print}' data.txt
# 第1个字段等于"John"的行
awk '$1 == "John" {print}' file.txt
# 多条件组合
awk '$1 == "John" && $3 > 100 {print}' file.txt
awk '$1 == "John" || $2 == "Smith" {print}' file.txt
5. BEGIN 和 END 块
# 在开始前执行
awk 'BEGIN{print "开始处理..."} {print $0}' file.txt
# 在结束后执行
awk '{print $0} END{print "处理完成"}' file.txt
# 组合使用
awk 'BEGIN{FS=":"; OFS="\t"} {print $1, $3} END{print "总计行数:", NR}' file.txt
常用操作
1. 计算和统计
# 求第2列的和
awk '{sum += $2} END{print "总和:", sum}' data.txt
# 求平均值
awk '{sum += $2; count++} END{print "平均值:", sum/count}' data.txt
# 最大值
awk 'NR==1 {max=$2} $2>max {max=$2} END{print "最大值:", max}' data.txt
2. 格式化输出
# 使用printf格式化输出
awk '{printf "姓名:%-10s 年龄:%3d\n", $1, $2}' data.txt
3. 字符串操作
# 获取字符串长度
awk '{print length($1)}' file.txt
# 截取子串
awk '{print substr($1, 1, 3)}' file.txt # 取前3个字符
# 替换字符串
awk '{gsub(/old/, "new", $0); print}' file.txt
实际应用示例
示例 1:处理/etc/passwd
# 提取用户名和shell
awk -F: '{print $1, $7}' /etc/passwd
# 查找bash用户
awk -F: '$7 ~ /bash/ {print $1}' /etc/passwd
示例 2:统计日志
# 统计IP访问次数
awk '{ip[$1]++} END{for(i in ip) print i, ip[i]}' access.log
# 按访问次数排序
awk '{ip[$1]++} END{for(i in ip) print i, ip[i]}' access.log | sort -k2 -nr
示例 3:数据转换
# CSV转TSV
awk 'BEGIN{FS=","; OFS="\t"} {print $1, $2, $3}' data.csv
# 重组数据
awk '{print $3, $1, $2}' file.txt
示例 4:条件判断
# 成绩分类
awk '{
if($2 >= 90) grade="A";
else if($2 >= 80) grade="B";
else if($2 >= 70) grade="C";
else grade="D";
print $1, $2, grade
}' scores.txt
实用技巧
1. 多个命令
awk '{
print $1
print "---"
}' file.txt
2. 内置函数
awk '{print toupper($1)}' file.txt # 转大写
awk '{print tolower($1)}' file.txt # 转小写
3. 范围模式
# 打印从匹配"start"到匹配"end"的所有行
awk '/start/,/end/' file.txt
4. 变量使用
awk '{total += $2; count++} END{avg=total/count; print "平均值:", avg}' data.txt
留下评论