概述
- 以下是Linux
awk
命令的详细教程,包含语法、内置变量、模式匹配、函数及高级用法 - 资料已经分类整理好:
https://pan.quark.cn/s/26d73f7dd8a7
1. 基本概念与语法
awk
是强大的文本处理工具,按行读取文本并按列处理数据,常用于格式化输出、数据提取和统计。
核心语法:
awk '模式 {动作}' 输入文件
- 模式:可选,用于筛选行(如正则表达式、条件表达式)。
- 动作:对匹配行执行的操作(如打印、计算)。
执行流程:
- 读取一行数据。
- 检查是否匹配模式。
- 若匹配则执行动作,否则跳过。
- 重复直到文件结束。
2. 内置变量
awk
内置了多个变量用于处理文本:
变量 | 含义 | 示例 |
---|---|---|
$0 | 当前整行内容 | awk '{print $0}' file |
$1, $2... | 当前行的第N个字段(列) | awk '{print $2, $3}' |
NF | 当前行的字段总数(列数) | awk '{print NF}' |
NR | 当前处理的行号 | awk '{print NR, $1}' |
FNR | 当前文件的行号(多文件时) | awk '{print FNR}' |
FS | 输入字段分隔符(默认空格或制表符) | awk -F: '{print $1}' |
OFS | 输出字段分隔符 | awk '{OFS="\t"}' |
RS | 输入记录分隔符(默认换行符) | awk -v RS="" '{print $1}' |
ORS | 输出记录分隔符(默认换行符) | awk '{ORS="---"}' |
3. 基本用法示例
3.1 打印指定列
# 打印每行的第1列和第3列
awk '{print $1, $3}' data.txt
# 以冒号为分隔符,打印第1列和第7列(如 /etc/passwd)
awk -F: '{print $1, $7}' /etc/passwd
3.2 条件筛选
# 打印第3列大于10的行
awk '$3 > 10 {print $0}' data.txt
# 打印包含 "error" 的行
awk '/error/ {print $0}' logs.txt
3.3 统计计算
# 计算第2列的总和
awk '{sum += $2} END {print "Sum:", sum}' data.txt
# 计算第3列的平均值
awk '{sum += $3} END {print "Avg:", sum/NR}' data.txt
# 统计行数
awk 'END {print "Total lines:", NR}' data.txt
4. 模式与动作详解
4.1 模式类型
- 正则表达式:
/pattern/
# 打印包含 "apple" 的行 awk '/apple/ {print $0}' fruits.txt
- 条件表达式:
条件 {动作}
# 打印第1列等于 "user1" 且第3列大于5的行 awk '$1 == "user1" && $3 > 5 {print $0}' data.txt
- 范围模式:
开始模式,结束模式
# 打印从 "START" 到 "END" 之间的所有行 awk '/START/,/END/ {print $0}' log.txt
- 特殊模式:
BEGIN
:处理文件前执行(常用于初始化)。END
:处理文件后执行(常用于输出汇总结果)。
awk 'BEGIN {print "开始处理"; FS=","} {print $1, $2} END {print "处理完成"}' data.csv
4.2 动作语句
- 打印:
print
和printf
# 格式化输出(类似C语言的printf) awk '{printf "姓名: %-10s 年龄: %d\n", $1, $2}' users.txt
- 变量赋值:
awk '{total = $2 + $3; print $1, total}' data.txt
- 条件语句:
awk '{if ($3 > 10) print $1, "High"; else print $1, "Low"}' data.txt
- 循环语句:
# 遍历每行的所有字段 awk '{for (i=1; i<=NF; i++) print "字段" i ":", $i}' data.txt
5. 内置函数
awk
提供了丰富的内置函数,用于字符串处理、数学计算等:
5.1 字符串函数
函数 | 作用 | 示例 |
---|---|---|
length(string) | 返回字符串长度 | awk '{print length($1)}' |
sub(regex, repl, string) | 替换首次匹配 | awk '{sub(/old/, "new", $1)}' |
gsub(regex, repl, string) | 替换所有匹配 | awk '{gsub(/apple/, "fruit", $0)}' |
index(str, substr) | 返回子串位置 | awk '{print index($0, "test")}' |
substr(str, start, len) | 提取子串 | awk '{print substr($1, 2, 4)}' |
5.2 数学函数
函数 | 作用 | 示例 |
---|---|---|
sqrt(x) | 平方根 | awk '{print sqrt($1)}' |
int(x) | 取整 | awk '{print int(3.14)}' |
rand() | 随机数(0~1) | awk '{print rand()}' |
srand(seed) | 设置随机数种子 | awk 'BEGIN {srand(); print rand()}' |
6. 高级用法示例
6.1 数据统计与分组
# 统计各部门的工资总和
awk -F, '{dept[$1] += $2}
END {for (d in dept) print d, dept[d]}' employees.csv
# 输出:
# IT 25000
# HR 18000
# Sales 32000
6.2 多文件处理
# 合并两个文件的第1列和第2列
awk 'FNR==NR {a[FNR]=$1; next} {print a[FNR], $2}' file1.txt file2.txt
6.3 复杂条件筛选
# 打印第2列重复的行(查找重复值)
awk '{a[$2]++}
a[$2] > 1 {print $0}' data.txt
6.4 自定义分隔符
# 使用竖线(|)作为分隔符
awk -F'|' '{print $1, $3}' pipe_data.txt
# 动态设置分隔符(如同时支持空格和逗号)
awk -F'[ ,]+' '{print $1, $2}' mixed_data.txt
7. 脚本文件与实战
7.1 创建 awk 脚本文件
创建script.awk
:
#!/usr/bin/awk -f
# 计算每行数值的平方和
BEGIN {
FS=","
print "开始计算..."
}
{
sum = 0
for (i=1; i<=NF; i++) {
sum += $i * $i
}
print "行" NR "的平方和:", sum
}
END {
print "计算完成!"
}
执行:
chmod +x script.awk
./script.awk data.csv
7.2 实战案例
# 分析 Apache 日志,统计各 IP 的访问次数
awk '{ips[$1]++}
END {for (ip in ips) print ip, ips[ip] | "sort -rn -k2"}' access.log
# 监控磁盘使用率,超过80%则报警
df -h | awk 'NR > 1 {sub(/%/, "", $5); if ($5 > 80) print $1, $5"% 已报警"}'
8. 注意事项
- 变量区分大小写:
awk
中变量严格区分大小写。 - 字符串比较用双引号:
$1 == "apple"
而非$1 == apple
。 - 正则表达式元字符:
.
、*
、^
等需注意转义。 - 性能优化:处理大文件时,避免过多的字符串操作和循环。
9. 总结
awk
的核心优势在于按列处理文本和灵活的模式匹配,适合:
- 数据提取与格式化
- 统计分析(求和、平均、分组)
- 日志解析与监控
- 自动化文本处理
通过组合内置变量、函数和自定义逻辑,awk
可以高效完成复杂的文本处理任务,是Linux系统中不可或缺的工具之一。