程序构成
样例文件 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) {
}
浙公网安备 33010602011771号