程序构成
样例文件 emp.data
雇员 单价 工时
Beth 4.00 0
Dan 3.75 0
Kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
e.g_1: 打印每位雇员的名称和报酬(单价*工时), 雇员的工作时长必须大于0
awk '{print $1, $2 * $3}' emp.data
awk '$3 > 0 {print $1, $2 * $3}' emp.data
$n: 代表第几个字段
{print $1, $2 * $3}: 代表动作
$3 > 0: 代表模式
e.g_2: 查找没有来工作的人的信息
awk '$3 == 0 {print $0}' emp.data
$0: 当前行的数据
{print $0}: 动作
$3 > 0: 模式
由此可见, awk 程序的组成结构是
awk 'program' input_files(可以是多个文件)
program:
模式 {动作}
...
每一行 awk 程序都是由多个 `模式{动作}` 组成的
awk 的基本工作方式
每一个输入行轮流被每一个模式测试, 每匹配一个模式, 对应的动作就会执行
模式或动作都可以被省略, 但不能同时省略
`省略模式`: 代表模式测试永远为真, 执行动作
`省略动作`: 若模式测试为真, 则输出当前行
杂项
如何测试自己写的 awk 程序是否正确?
awk 'program'
> 手动输入行信息看输出
以上说的都是一些程序比较简短的, 若程序较长, 可将程序写入文件
awk -f program_file input_files
print 与 printf 的区别
`print`: 打印输出, 自带换行
`printf`: 可以格式化输出, 无法自带换行
`%-8s`: 占用8个字符, -代表左对齐
`%8.2f`: 占用8个字符, 精确到2位小数
e.g_3: 根据每个人的报酬升序输出?
awk '{printf("%6.2f %s\n", $2 * $3, $0)}' emp.data | sort -n
功能点
模式
-
BEGIN
-
END
-
expression
-
/regular expression/
-
compund pattern
复合模式: &&, ||, !
-
pattern1, pattern2
范围模式: 输入行从匹配 pattern1 的行开始, 到匹配 pattern2 的行结束
-
e.g_4: 求出 emp.data 的平均报酬
awk '{cou = cou + 1; pay = pay + $2 * $3; print $0} END {print "avg = ", pay / cou}' emp.data
- e.g_5: 求出报酬最多的那个人
awk '$2 * $3 > m {m = $2 * $3; r = $0} END {print m, r}' emp.data
内建变量
变量名 | 描述 |
---|---|
ARGC | 命令行参数的个数 |
ARGV | 命令行参数数组 |
FNR | 当前输入文件的记录个数 |
FS | 输入记录的字段分隔符 |
NF | 当前输入记录的字段个数 |
NR | 当前记录行数 |
OFMT | 数值的输出格式 |
OFS | 输出字段分隔符 |
ORS | 输出记录分隔符 |
RLENGTH | 被函数 match 匹配的字符串的长度 |
RS | 输入行的记录分隔符 |
RSTART | 被函数 match 匹配的字符串的开始 |
SUBSEP | 下标分隔符 |
内建函数
变量名 | 描述 |
---|---|
atan2 | |
cos | |
exp | |
int | |
log | |
rand | |
sin | |
sqrt | |
srand | |
gsub | |
index | |
length | |
match | |
split | |
sprintf | |
sub | |
substr | |
getline |
流程控制
-
if ...
-
if ... else ...
-
if ... else if ...
-
if ... else if ... else ...
-
while ...
-
for ...
-
e.g_6: 打印名字长度是 4 的数据信息
awk '{if (length($1) == 4) {print $0;}}' emp.data
数组
-
variable in array
-
delete array[i]
-
多维: (i, j) in array
-
e.g_7: 倒序输出一个文件的数据
{
line[NR] = $0;
i = i + 1;
}
END {
while (i > 0) {
print line[i];
i = i - 1;
}
}
自定义函数
function funcName(params) {
}