前言
在现代数据驱动的场景中,文本数据的处理与分析已成为系统管理、数据分析和开发工作中不可或缺的一部分。从服务器日志的实时解析到大规模数据集的清洗与统计,从配置文件调整到自动化报告生成,高效的文本处理能力直接决定了任务的完成效率与成果质量。作为一款内置于操作系统的文本处理利器,awk
不仅能轻松应对日志分析、数据过滤和列操作,还能在数值计算、条件筛选和数据聚合等复杂任务中大显身手。
如果说基础篇为你打开了 awk
的大门,那么本篇(中篇)将带你深入探索其核心功能。我们将聚焦于以下内容:
- 数值计算:从浮点运算到逐行统计,展示
awk
在数据处理中的灵活性。 if
语句:通过条件判断实现精准筛选,结合正则表达式完成复杂逻辑。for
循环:遍历字段或执行聚合操作,处理多维度数据。while
循环:动态控制流程,适应更复杂的处理需求。- 综合应用:编写数据分析脚本,汇总和处理大规模数据。
从简单的运算到复杂的逻辑控制,我们将逐步解锁 awk
的强大潜力,让你在文本处理和数据分析的道路上更进一步。让我们开始这场从基础到进阶的探索之旅吧!
计算:从简单运算到数据统计
awk
的计算能力是其核心优势之一。无论是简单的数学运算还是大规模数据的统计分析,awk
都能以高效的方式完成任务。以下从基础运算入手,逐步扩展到按行计算和列值累加。
支持浮点数运算
与 Shell 脚本默认仅支持整数运算不同,awk
天生支持浮点数计算,使其在需要精确结果的场景中表现卓越。例如:
awk 'BEGIN {print 10/3}'
运行后输出 3.3333333333333335
。相比之下,Shell 中的 $((10/3))
仅返回整数 3
,而 awk
的浮点运算能力显然更适合财务计算、科学数据分析等场景。
BEGIN
块的使用还使得这条命令无需输入文件即可运行,体现了 awk
在独立计算中的灵活性。无论是加减乘除还是内置数学函数(如 sqrt()
、sin()
),awk
都能轻松胜任。
按行计算
在实际工作中,我们常需对文件的每一行进行计算。例如,假设文件 data.txt
内容如下:
item1 10 20 30
item2 15 25 35
计算每行第 3、4、5 列的总和并输出:
awk '{sum = $3 + $4 + $5; print $0, sum, sum/3}' data.txt
输出:
item1 10 20 30 80 26.6667
item2 15 25 35 75 25
执行逻辑:
sum = $3 + $4 + $5
:计算第 3、4、5 列的和,存入变量sum
。print $0, sum, sum/3
:打印整行、总和及平均值。$0
表示当前行完整内容,字段默认以空格分隔。
这种按行计算非常适合处理结构化数据,如统计日志响应时间或计算 CSV 文件数值列。
累加列值
当需要全局统计某列时,awk
的累加特性大放异彩。例如,计算所有行第 1 列的总和:
awk '{total += $1} END {print total}' data.txt
假设 data.txt
为:
5 apple 10
3 banana 20
8 orange 15
输出:
16
解析:
{total += $1}
:每行将第 1 列累加到total
,未初始化时默认为 0。END {print total}
:处理完所有行后输出结果。
此方法适用于统计错误次数、销售总额等场景。多列累加只需增加变量:
awk '{sum1 += $1; sum2 += $2} END {print sum1, sum2}' data.txt
if
语句:灵活的条件控制
条件判断是编程的核心逻辑,awk
提供类似 C 语言的 if
语句,结合模式匹配能力,使其在文本处理中更智能。
基本语法
if
语句格式:
if (condition) {
action
}
- condition:条件表达式,如比较运算(
$1 > 10
)、逻辑运算($1 > 0 && $2 < 100
)或正则匹配($0 ~ /error/
)。 - action:条件为真时执行的操作。
单语句省略大括号
若只有一条语句,可省略 {}
:
if (condition) action
例如:
awk '{if ($2 > 80) print $0}' data.txt
等价于:
awk '$2 > 80 {print $0}' data.txt
示例 1:筛选高值行
假设 data.txt
为:
item1 85 10
item2 75 20
item3 90 15
运行:
awk '$2 > 80 {print $0}' data.txt
输出:
item1 85 10
item3 90 15
示例 2:if-else
语句
分支逻辑示例:
awk '{if ($2 > 80) print "High"; else print "Low"}' data.txt
输出:
High
Low
High
多语句需用大括号:
awk '{if ($2 > 80) {print "High"; print $0} else {print "Low"; print $0}}' data.txt
输出:
High
item1 85 10
Low
item2 75 20
High
item3 90 15
注意事项
-
多语句需大括号
省略大括号会导致逻辑错误,如:awk '{if ($2 > 80) print "High"; print $0}' # 错误
-
嵌套
if
示例:awk '{if ($1 > 50) {if ($2 > 80) print $0}}'
-
可读性
复杂脚本中保留大括号提升维护性。
配合正则表达式:复杂匹配的利器
awk
的模式匹配与条件判断结合,借助正则表达式实现强大筛选功能。
示例 1:筛选特定模式
筛选以 -
开头且第 2 列大于 80 的行:
awk '/^-/ && $2 > 80 {print $0}' data.txt
data.txt
:
-item1 85 10
item2 75 20
-item3 90 15
输出:
-item1 85 10
-item3 90 15
示例 2:排除模式
排除含 “asd” 的行:
awk '!/asd/' data.txt
等价于:
awk '{if ($0 !~ /asd/) print $0}' data.txt
示例 3:复杂逻辑
标记高低值:
awk '/^-/ {if ($2 > 80) print "High: "$0; else print "Low: "$0}' data.txt
输出:
High: -item1 85 10
High: -item3 90 15
for
循环:遍历与聚合
for
循环类似 C 语言,适合遍历字段或聚合数据。
基本语法
for (init; condition; increment) {
action
}
示例 1:遍历字段
打印每行所有字段:
awk '{for (i = 1; i <= NF; i++) print $i}' data.txt
输出:
-item1
85
10
item2
75
20
-item3
90
15
示例 2:奇数列
打印奇数列:
awk '{for (i = 1; i <= NF; i += 2) printf $i " "} {print ""}' data.txt
输出:
-item1 10
item2 20
-item3 15
示例 3:列总和
计算每行总和:
awk '{sum = 0; for (i = 1; i <= NF; i++) sum += $i; print sum}' data.txt
data.txt
:
1 2 3
10 20 30
输出:
6
60
while
循环:动态流程控制
while
循环为 awk
提供了动态控制能力,特别适合处理不确定次数的迭代或外部输入。
基本语法
while (condition) {
action
}
- condition:每次循环前检查,若为真则执行。
- action:循环体内操作。
示例 1:累加到阈值
累加第 1 列直到超过 10:
awk '{sum = 0; while (sum <= 10) {sum += $1; print sum}}' data.txt
data.txt
:
3 apple
4 banana
5 orange
输出:
3
7
12
解析:
sum += $1
:每次加第 1 列。sum <= 10
:条件控制循环。
示例 2:结合 getline
从外部命令读取数据:
awk 'BEGIN {while ("whoami" | getline) print $0}'
输出当前用户名,getline
从管道读取每次一行,直到结束。
示例 3:遍历字段直到条件
打印字段直到遇到负数:
awk '{i = 1; while (i <= NF && $i >= 0) {print $i; i++}}' data.txt
data.txt
:
5 10 -3 20
2 8 15 4
输出:
5
10
2
8
15
4
解析:
i <= NF && $i >= 0
:字段序号不超过总数且值非负。i++
:递增索引。
注意事项
-
无限循环风险
确保条件最终为假,否则需用break
跳出:awk 'BEGIN {i = 0; while (i < 5) {print i; i++; if (i == 3) break}}'
-
与
for
对比
for
适合已知次数迭代,while
适合动态条件。
小结
本篇深入探索了 awk
的计算、条件判断、循环控制(for
和 while
)及正则表达式应用,展示了其在文本处理中的强大能力。主要内容包括:
- 计算:支持浮点运算、逐行计算和列值累加。
if
语句:灵活条件判断,单语句可省大括号。- 正则表达式:结合模式匹配实现复杂筛选。
for
循环:遍历字段和聚合数据。while
循环:动态控制流程,处理不确定迭代。
这些技能让你能高效应对从简单筛选到复杂分析的任务,为后续高级应用打下基础。下一阶段将聚焦脚本编写与大规模数据处理,敬请期待!