gawk是什么?
gawk是GNU AWK,是awk的GNU实现版本。awk 是一种强大的文本处理语言,而不仅仅是像 grep 或 sed 那样简单的命令。gawk可以看作是专门为处理结构化文本文件(特别是以空格或制表符分隔的字段)而设计的微型编程语言。
与sed命令相比:
sed 是一个流编辑器,按行处理,主要针对单行进行替换、删除、插入等操作。
gawk 是一个报告生成器,它逐行读取文本,但可以将一行拆分成多个字段,并进行更复杂的逻辑操作,如算术运算、变量赋值、流程控制、函数调用等,最终可以格式化输出结构化报告。
现在基本上主流的linux操作系统中都已经安装了gawk,而且awk命令是一个软连接(符号链接),指向的就是gawk。
kwephis70674332:~ # ll /usr/bin/awk
lrwxrwxrwx 1 root root 4 Aug 11 2025 /usr/bin/awk -> gawk
所以说awk和gawk两个命令,使用哪个都可以,都是一样的,而且很多人还是习惯使用awk。
基本语法
gawk [选项] '程序指令' 输入文件1 输入文件2 ...
gawk程序指令的格式是:'/模式/{动作}'
- 模式:一个条件。gawk 只对满足该条件的行执行 动作。如果模式为空,则对所有行执行动作。
- 动作:一条或多条语句。语句之间用分号 ; 分隔。如果动作是 print 或 printf 等默认的动作,{} 可以省略。
接下来我们先创建一个示例文件data.txt,就用这个示例文件文件来演示大部分功能用法,内容如下:
-
用户ID 用户名 分数 科目 101 张三 85 数学 102 李四 92 英语 103 王五 78 数学 104 赵六 88 物理 105 孙七 95 数学
工作原理
gawk 执行过程如下:
- 初始化:读取并分析整个程序指令。
- 读取:从输入文件(或标准输入)中按行读取记录。
- 分割:使用域分隔符(默认是空格或制表符)将每行记录分割成一个个字段。
- 执行:
如果定义了处理模式(BEGIN),则首先执行。
对每一行输入:
检查行是否匹配给定的 模式。
如果匹配,则执行相应的 动作。
如果定义了处理模式(END),则在处理完所有行后执行。
5. 输出:在执行过程中,将 print 或 printf 的输出打印到标准输出。
核心概念详解
记录与字段
- 记录:通常就是指输入的一行文本。
- 字段:一行文本被分割后的片段。默认的分割符是连续的空格和制表符。
下面是一些专用变量
$0:整行的文本内容。
$1, $2, $3, ...:代表第一个、第二个、第三个...字段。
NF:Number of Fields(当前行的字段数量)。
NR:Number of Records(已处理的记录总数,也就是行号)。
FILENAME:当前正在处理的文件名。
FS:Field Separator(输入字段分隔符),默认为空格。
OFS:Output Field Separator(输出字段分隔符),默认为空格。
RS:Record Separator(记录分隔符),默认为换行符。
接下来看一个示例
# 打印 data.txt 文件的每一行,并显示行号和该行字段数
gawk '{print "行号:", NR, "共", NF, "个字段 ->", $0}' data.txt
# 输出
行号: 1 共 4 个字段 -> 用户ID 用户名 分数 科目
行号: 2 共 4 个字段 -> 101 张三 85 数学
行号: 3 共 4 个字段 -> 102 李四 92 英语
... (后续行省略) ...
# 只打印用户名(第2个字段)和分数(第3个字段)
gawk '{print $2,$3}' data.txt
# 输出
张三 85
李四 92
...
模式
模式决定了动作执行的条件。
- 未定义模式,则对每一行都执行;
- 正则表达式模式:用 /正则/ 表示,匹配该正则表达式的行会执行动作。
- 关系表达式模式:如 x > y, x == y, x != y。表达式为真时执行。
# 打印所有包含 "数学" 的行
gawk '/数学/{print $0}' data.txt
# 只打印分数大于等于 90 的用户的用户名和分数
gawk '$3 >= 90 {print $2,$3}' data.txt
# 打印科目是 "数学" 的行
gawk '$4 == "数学" {print$2, $3}' data.txt
- BEGIN 模式:在读取任何输入行之前执行一次。通常用于初始化变量、打印表头等。
- END 模式:在所有输入行处理完毕之后执行一次。通常用于打印汇总信息、统计数据等。
BEGIN 块在程序开始时运行,打印一个表头。OFS="\t" 将输出字段的分隔符设置为制表符,使对齐更美观。
# 打印一个漂亮的表格
gawk '
BEGIN {
printf "======= 数学成绩单 =======\n";
OFS="\t"
}
$4=="数学" {
print$1, $2,$3
}' data.txt
# 输出
======= 数学成绩单 ========
101 张三 85
103 王五 78
105 孙七 95
END模式示例如下:
# 计算 "数学" 科目的平均分
gawk '
BEGIN {
total_score = 0
count = 0
print "正在计算数学平均分..."
}
$4 == "数学" {
total_score +=$3
count++
}
END {
if (count > 0) {
printf "数学科目平均分是: %.2f\n", total_score / count
} else {
print "没有找到数学成绩。"
}
}' data.txt
# 输出
正在计算数学平均分...
数学科目平均分是: 86.00
动作
动作有gawk语句组成,常用的动作介绍如下:
1、print:输出列表
- print $1,$3:用默认的 OFS(空格)连接并输出。
- print 或 print $0:输出整行。
- print "abc":直接输出字符串。
2、printf:格式化输出(类似 C 语言),更强大、更精确。
语法如下:
printf "格式字符串", 变量1, 变量2, ...
常用的格式化符有:
- %d :整数
- %f :浮点数
- %.2f:保留两位小数的浮点数
- %s :字符串
- \t :制表符
- \n :换行符
# 格式化输出
gawk '
BEGIN {
printf "%-8s %s\n", "姓名", "分数";
print "---------- ------"
}
$4=="数学" {
printf "%-8s %d\n",$2, $3
}' data.txt
# 输出
姓名 分数
------ ------
张三 85
王五 78
孙七 95
3、复制和运算
# 找出最高分
gawk '
BEGIN {max_score=0} $3 > max_score {max_score=$3}
END {print "最高分是:", max_score}
' data.txt
4、流程控制 if-else, for, while
# 简单的 if-else
gawk '
$3 >= 90 {print$2, "成绩优秀"}
$3 < 90 {print$2, "继续努力"}
' data.txt
常用选项
-F 或 --field-separator选项:作用是指定字段分隔符。这是最常用的选项之一,例如处理用逗号分隔的 CSV 文件。
# 在命令行定义一个变量 subject=数学,在程序中使用
gawk -v subject="数学" -F ',' '$3 == subject {print$1, $2}' data.csv
-v 或 --assign选项:作用是从命令行向 gawk 程序中传递变量。
# 在命令行定义一个变量 subject=数学,在程序中使用
gawk -v subject="数学" -F ',' '$3 == subject {print$1, $2}' data.csv
假设有一个 sales.txt 文件,记录了各商店的销售额。我们来演示一下gawk在数据分析与统计方面的应用。
北京店 12000 8000 15000
上海店 20000 18000 17000
广州店 9500 11000 10500
命令编写如下:
gawk '
# BEGIN模式
BEGIN {
OFS = "\t" # 设置输出字段分隔符为制表符
print "店名", "总销售额"
print "--------------------"
}
# 动作
{
# $1是店名,$2, $3,$4是季度销售额
store_total = $2 +$3 + $4
company_total += store_total # 累加到公司总计
printf "%s\t%d\n",$1, store_total
}
# END模式
END {
print "--------------------"
print "公司总销售额:", company_total
}' sales.txt
# 输出
店名 总销售额
--------------------
北京店 35000
上海店 55000
广州店 31000

1341

被折叠的 条评论
为什么被折叠?



