AWK命令详解与应用案例
AWK是一种强大的文本处理工具,适用于结构化文本数据的处理、分析和报告生成。它以三位创始人(Aho、Weinberger和Kernighan)的姓氏首字母命名。
基本语法
awk 'pattern {action}' file
或通过管道:
command | awk 'pattern {action}'
AWK工作原理
- 逐行读取输入文件
- 按指定的字段分隔符(默认为空格)将每行分割成多个字段
- 检查每行是否匹配指定的模式
- 对匹配的行执行相应的动作
内置变量
| 变量 | 描述 |
|------|------|
| $0
| 整行内容 |
| $1
-$n | 第1到第n个字段 |
| NF
| 当前行的字段数 |
| NR
| 当前处理的行号 |
| FNR
| 当前文件中的行号(处理多个文件时有用) |
| FS
| 输入字段分隔符(默认为空格) |
| OFS
| 输出字段分隔符(默认为空格) |
| RS
| 输入记录分隔符(默认为换行符) |
| ORS
| 输出记录分隔符(默认为换行符) |
| FILENAME
| 当前处理的文件名 |
常用操作符
- 算术运算符:
+
,-
,*
,/
,%
,^
(幂运算) - 比较运算符:
==
,!=
,>
,<
,>=
,<=
- 逻辑运算符:
&&
,||
,!
- 匹配运算符:
~
(匹配正则),!~
(不匹配正则)
应用案例
1. 基本打印操作
# 打印文件的列
awk '{print $1}' file.txt
# 打印文件的和第三列
awk '{print $1,$3}' file.txt
# 打印行号及整行内容
awk '{print NR, $0}' file.txt
2. 条件筛选
# 打印第二列大于100的行
awk '$2 > 100 {print $0}' file.txt
# 打印包含"error"的行
awk '/error/ {print}' file.txt
# 打印列为"admin"的行
awk '$1 == "admin" {print}' file.txt
3. 字段处理
# 计算第三列的总和
awk '{sum += $3} END {print sum}' file.txt
# 计算文件的行数
awk 'END {print NR}' file.txt
# 打印字段数大于3的行
awk 'NF > 3 {print $0}' file.txt
4. 高级应用
# 统计IP访问次数(假设列为IP)
awk '{ip_count[$1]++} END {for(ip in ip_count) print ip, ip_count[ip]}' access.log
# 计算文件大小总和(第五列为文件大小)
ls -l | awk '{sum += $5} END {print sum/1024/1024 " MB"}'
# 提取特定格式的日期(如从"2023-08-15"提取年月)
awk -F'-' '{print $1 "-" $2}' dates.txt
# 处理CSV文件(设置逗号为分隔符)
awk -F, '{print $2,$3}' data.csv
# 多文件处理,在每个文件前打印文件名
awk 'FNR==1 {print "--- Processing:", FILENAME} {print $0}' file1.txt file2.txt
5. BEGIN和END块
# 添加表头
awk 'BEGIN {print "Name\tAge\tScore"} {print $1"\t"$2"\t"$3}' data.txt
# 计算平均值
awk '{sum += $1} END {print "Average:", sum/NR}' numbers.txt
6. 自定义函数
# 定义并使用简单函数
awk '
function to_upper(str) {
return toupper(str)
}
{print to_upper($1)}
' file.txt
7. 字符串处理
# 连接字符串
awk '{print $1 "-" $2}' file.txt
# 获取字符串长度
awk '{print length($1)}' file.txt
# 子字符串提取
awk '{print substr($1, 1, 3)}' file.txt
实用技巧
-
修改字段分隔符:
awk -F':' '{print $1}' /etc/passwd # 使用冒号分隔
-
同时处理多个文件:
awk '{print FILENAME, $0}' file1.txt file2.txt
-
输出重定向:
awk '{print > $1".txt"}' data.txt # 按列内容输出到不同文件
-
使用正则表达式:
awk '/^[0-9]+$/ {print "Number:", $0}' file.txt # 匹配纯数字行
-
格式化输出:
awk '{printf "%-10s %5d\n", $1, $2}' data.txt
AWK功能强大,以上只是其功能的冰山一角。通过组合这些基本功能,可以解决复杂的文本处理问题。