简介
awk 是一种强大的文本处理工具,可以用于处理结构化的文本数据。它可以根据指定的模式和动作来筛选、处理和格式化文本。
下面是一些常见的 awk 命令使用方法。
详细介绍
基本语法:
awk 'pattern { action }' filename
其中,pattern 是用于匹配文本的条件表达式,action 是在匹配到的文本上执行的动作,filename 是要处理的文件名(可以省略,默认为标准输入)。
显示整行:
awk '{ print }' filename
这个命令将显示文件中的每一行。
按列显示:
awk '{ print $1, $2 }' filename
这个命令将按空格或制表符分隔文本,然后显示每一行的第一个和第二个列。
使用分隔符定制列:
awk -F',' '{ print $1, $2 }' filename
这个命令将使用逗号作为分隔符,然后显示每一行的第一个和第二个列。
使用条件过滤行:
awk '/pattern/ { print }' filename
这个命令将只显示匹配到 pattern 的行。
使用条件过滤并处理列:
awk '/pattern/ { print $1, $2*2 }' filename
这个命令将只处理匹配到 pattern 的行,并显示每一行的第一个列和第二个列乘以 2 的结果。
使用内置变量:
awk '{ print NR, $0 }' filename
这个命令将显示行号(NR)和每一行内容。
使用条件分支:
awk '{ if ($3 > 10) print $1, $2 }' filename
这个命令将按照条件分支,只显示第三列大于 10 的行的第一列和第二列。
显示包含特定单词的行:
awk '/word/' filename
这个命令会输出包含"word"的行。
计算并显示文件中数字的总和:
awk '{ total += $1 } END { print "Sum: " total }' filename
这个命令会计算文件中第一列数字的总和,并在处理完所有行后输出结果。
找出文件中最长的行:
awk 'length > max_length { max_length = length; longest_line = $0 } END { print longest_line }' filename
这个命令会找出文件中最长的一行,并输出该行的内容。
脚本实战
接下来,让我们创建一个简单的 awk 脚本示例。假设我们有一个名为 example.txt 的文本文件,内容如下:
Alice 25
Bob 30
Charlie 28
Diana 22
我们可以使用 awk 脚本来计算年龄的平均值。创建名为 age_avg.awk 的文件,内容如下:
# age_avg.awk
{
sum += $2
}
END {
avg = sum / NR
print "Average age is " avg
}
然后,我们可以在命令行中运行以下命令来执行该脚本并对文件进行处理:
awk -f age_avg.awk example.txt
这将输出:
Average age is 26.25
这段代码是一个简单的 awk 脚本,用于计算给定文件中包含的数字列的平均值。让我解释一下这个脚本的工作原理:
{ sum += $2 }:
这是一个动作部分,它告诉 awk 对于每一行(由默认模式匹配),将第二列的值加到 sum 变量中。
END { avg = sum / NR; print "Average age is " avg }:
这部分在 awk 处理完所有输入行后执行。在这里,我们计算平均值并输出结果。
avg = sum / NR:计算平均值,即所有第二列数字的总和除以输入行的数量(NR 表示输入行的数量)。
print "Average age is " avg:打印计算得到的平均值。
通过这个例子,我们定义了一个处理模式和动作的 awk 脚本,用于计算文件中第二列数字的平均值,如图:
示例二:
假设有一个包含学生成绩的文本文件,格式如下:
vim grades.txt
Alice 90
Bob 85
Charlie 92
Diana 78
我们想要创建一份报告,包含每个学生的成绩统计信息和总体班级平均成绩。创建一个名为 grade_report.awk 的文件,内容如下:
# grade_report.awk
# BEGIN 部分在处理输入之前执行,用于打印报告的标题和表头
BEGIN {
print "----- Grade Report -----" # 打印报告标题
print "Name\tGrade" # 打印表头
print "------------------------"
}
# 主要处理部分,对每一行进行操作
{
name = $1 # 存储学生姓名
grade = $2 # 存储学生成绩
grades[name] += 1 # 统计每个学生的成绩次数
total[name] += grade # 统计每个学生的所有成绩总和
}
# END 部分在处理输入之后执行,用于生成最终的报告
END {
print "------------------------"
print "Name\t\tAverage Grade" # 打印平均成绩表头
print "------------------------"
# 遍历每个学生的成绩统计信息
for (name in grades) {
avg_grade = total[name] / grades[name] # 计算平均成绩
printf "%-10s\t%.2f\n", name, avg_grade # 打印学生姓名和平均成绩
}
num_students = length(grades) # 获取学生总数
sum_grades = 0 # 初始化总成绩总和
# 计算班级所有学生总成绩
for (name in total) {
sum_grades += total[name]
}
class_avg = sum_grades / num_students # 计算班级平均成绩
print "------------------------"
printf "Class Average:\t%.2f\n", class_avg # 打印班级平均成绩
}
然后,在命令行中运行以下命令来执行该脚本并对给定的成绩文件进行处理:
awk -f grade_report.awk grades.txt
现在让我详细解释这个脚本的各个部分:
BEGIN: 这部分包含在处理输入之前执行的代码。在这里,打印报告的标题和表头,为后续的处理做准备。
主要处理部分:
对于每一行,提取学生姓名和成绩,并使用数组 grades 统计每个学生的成绩次数,使用数组 total 统计每个学生的所有成绩总和。
END: 这部分包含在处理输入之后执行的代码。在这里,打印每个学生的平均成绩,然后计算所有学生的总成绩并计算班级的平均成绩。
遍历每个学生的成绩统计信息,计算每个学生的平均成绩并打印出来。
然后,计算班级中所有学生的总成绩,并计算出整个班级的平均成绩。
这将输出一个包含每个学生的平均成绩以及班级的平均成绩的报告,类似于以下内容:
----- Grade Report -----
Name Grade
------------------------
------------------------
Name Average Grade
------------------------
Alice 90.00
Bob 85.00
Charlie 92.00
Diana 78.00
------------------------
Class Average: 86.25
在这个例子中,使用了 awk 的数组功能来跟踪每个学生的成绩和计数,并在最后计算了总体班级的平均成绩。
#######################################################################################################################################################