Getting Started
通过例子快速入门, 在如下结构化的数据中
- 计算工作时长 > 0 的总薪资
- 显示时常 = 0 的用户
1 | cat emp.data |
The Structure of an AWK Program
格式 pattern { action }
, pattern 如果结果为 true 则执行 action 中定义的行为。然后执行下一行,一直到文本结束。
Running an AWK Program
awk 'program' input files
, 多文件 awk 'program' input file1 file2
, 不接文件,则从标准输入拿内容
可以将程序部分写到文件中 awk -f progfile optional_list_of_input_files
Simple Output
Print Event Line 没有写 pattern 表示每行都输出,{ print }
和 { print $0 }
等价,都是打印全部
Print Certain Fields { print $1, $3 }
NF, the Number of Fields 内置变量 NF 表示最后一个 field 的 number, 下面的例子答应 field 数量 + 名字 + 最后一个 field
1 | awk '{print NF, $1, $NF}' emp.data |
Computing and Printing field 可以直接用于计算 { print $1, $2 * $3 }
Printing Line Numbers NR 代表行号, number of row(record?)
1 | awk '{print NR, $0}' emp.data |
Putting Text in the Output 输出内容中加入自己的文本
1 | awk '{print "total pay for", $1, "is", $2 * $3}' emp.data |
Fancier Output
print 只是简单的打印内容,如果想要输出更丰富,使用 printf
Lining Up Fields printf 格式 printf(format, value1, value2..., valuen)
1 | awk '{printf("total pay for %s is %.2f\n", $1, $2 * $3)}' emp.data |
Sorting the Output 结合 pipe 进行排序
1 | awk '{printf("%6.2f %s\n", $2 * $3, $0)}' emp.data | sort |
Selection
Awk 的 pattern 可用于筛选数据
Selection by Comparison 通过比较筛选
1 | # 时薪大于5 |
Selection by Computation 结合计算筛选
1 | awk '$2 * $3 >= 50 { printf("$%.2f for %s\n", $2 * $3, $1)}' emp.data |
Selection by Text Content 文本匹配选择, == 精确匹配,/match/ 包含
1 | awk '$1 == "Susie"' emp.data |
Combinations of Patterns 使用 ||, && 做逻辑操作
1 | awk '$2 >= 4 || $3 >= 20' emp.data |
如果不加逻辑操作符号,则符合条件的语句会重复输出
‘$2 >= 4 || $3 >= 20’ 等价于 !($2 < 4 && $3 < 20)
Data Validation Awk 是一款很优秀的数据校验工具
1 | # 打印 field 不等于 3 的行 |
BEGIN and END 类似 before/after class 的操作
1 | awk 'BEGIN { print "NAME RATE HOURS"; print ""} { print }' emp.data |
Computing with AWK
pattern { action }
中的 action 是一系列用换行或冒号分割的语句。这节介绍一些字符,数字操作,一些内置变量和自定义变量。自定义变量不需要声明。
Counting 统计时长大于 15 的用户
1 | awk ' $3 > 15 { emp++; } END{ print emp, "employees worked more than 15 hours" }' emp.data |
Computing Sums and Averages 计算总值和平均值
1 | awk 'END { print NR, "employees" }' emp.data |
Handling Text Awk 有处理文字的能力, awk 中的变量可以持有数字和字符串,下面的例子显示报酬最多的用户
1 | awk ' |
可以看出来,默认的变量初始值为 0
String Concatenation 字符拼接
1 | awk '{ names = names $1 " " } |
names 变量的初始值为 null
Printing the Last Input Line 打印最后一行
1 | awk '{ last = $0 } END { print last }' emp.data |
Built-in Functions awk 提供了很多内置函数,比如 length 计算字符串长度
1 | awk '{ print $1, length($1) }' emp.data |
Counting Lines, Words and Characters 通过使用 length,NF, NR 统计行基本信息,为了便于计算,我们将每一个 field 都当作 String 对待
1 | awk '{ |
nc = nc + length($0) + 1
1 代表换行符
Control-Flow Statemnets
awk 中的流程控制和 C 语言中基本一直,这些控制语句只能用在 action 中
If-Else Statement
统计时薪大于 6 的所有人的总收入及平均收入, 通过 if-else 控制打印的 loop
1 | awk ' |
While Statement
while = condition + body. 下面实现一个计算存款的功能,表达式可以概括为 value = amount (1 + rate)years
1 | cat interest1 |
For Statement
同样的计算,用 for 实现
1 | cat interest2 |
Arrays
awk 支持数组。下面的实验中,我们在 action 中将行信息存到数组中,在 END 中通过 while 倒序输出
1 | awk ' |
A Handful of Useful “One-liners”
摘录一些简短但是令人印象深刻的 awk 脚本
- print the total number of input lines
awk 'END { print NR }' emp.data
- 打印第三行
awk 'NR == 3' emp.data
- 打印每行最后一个 field
awk '{ print $NF }' emp.data
- 打印最后一行的最后一个 field
awk '{ field = $NF } END { print field }' emp.data
- 打印 field 数量大于 4 的行
awk 'NF > 4' emp.data
- 打印最后一个 field 大于 4 的行
awk '$NF > 4' emp.data
- 用行号代替第一个 field
awk '{ $1 = NR; print }' emp.data
- 抹去第二个 field
awk '{ $2=""; print }' emp.data
- 倒序打印每一行
awk '{for(i=NF; i>0;i--) printf("%s", $i); printf("\n")}' emp.data