AWK SUMMARY
Reading Notes from classic book – The AWK Programming Language
Command
1 | awk [-Fs] 'program' optional list of filenames |
参数 -Fs 把字段分隔符 FS 设置成 s, 如果没有提供文件名, awk 就从标准输入读取数据. 文件名的形式
可以是 var=text, 在这种情况下, 相当于把 text 赋值给变量 var, 当这个参数被当作一个文件而被访问
时, 执行赋值操作.
Program Structure
一个 awk 程序由一系列的 模式–动作 语句和函数定义组成. 一个 模式–动作 语句具有形式:1
pattern { action }
如果某个动作省略了模式, 则默认匹配所有输入行; 如果某个模式省略了动作, 则默认打印匹配行. 一个函数定义具有形式:1
function name(parameter-list) { statement }
模式–动作 语句和函数定义由换行符或分号分隔, 并且这两个字符可以混合使用.
Pattern
- BEGIN
- END
- expression
- /regular expression/
- pattern && pattern
- pattern || pattern
- !pattern
- (pattern)
最后一个模式是范围模式, 它不能作为其他模式的组成部分. 类似地, BEGIN 和 END 也不能和其他
模式结合.
Action
- break
- continue
- delete array-element
- do statement while (expression)
- exit[expression]
- expression
- if (expression) statement [else statement]
- input-output statement
- for (expression; expression ; expression) statement
- for (variable in array) statement
- next
- return [expression]
- while (expression) statement
- { statement }
一个单独的分号表示空语句. 在一个 if-else 语句中, 如果第一个 statement 和 else 出现在同一行,
那么它必须以分号结尾, 或者用花括号包围起来. 类似地, 在 do 语句中, 如果 statement 和 while 出现
在同一行, 那么它必须以分号结尾, 或者用花括号包围起来.
Format
语句通过换行符或 (和) 分号隔开. 空行可以出现在任何语句, 模式–动作 语句, 或函数定义的前面
或后面. 空格与制表符可以插入到运算符或操作数的周围. 一条长语句可以通过反斜杠延续到下一行.
另外, 如果一条语句在逗号, 左花括号, &&, ||, do, else, if 或 for 的右括号后断行, 则不需要反斜杠.
由 # 开始的注释可以出现在任意一行的末尾.
Input/Output
I/O Functions | Interpretation |
---|---|
close(expr) | 关闭由 expr 指示的文件或管道 |
getline | 把 $0 设置成下一条记录; 同时设置 NF, NR, FNR |
getline <file | 把 $0 设置成文件 file 的下一条记录; 同时设置 NF |
getline var | 把 var 设置成下一条记录; 同时设置 NR, FNR |
getline var <file | 把 var 设置成文件 file 的下一条记录. |
打印当前记录 | |
print expr-list | 打印 expr-list 所表示的表达式 |
print expr-list >file | 把表达式输出到文件 file 中 |
printf fmt, expr-list | 格式化并输出 |
printf fmt, expr-list > file | 格式化并输出到文件 file 中 |
system(cmd-line) | 执行命令 cmd-line, 返回命令的退出状态 |
print 后面的 expr-list, 以及 printf 后面的 fmt, expr-list 可以用括号括起来. 在 print 和
printf 中, >>file 表示把输出追加到文件 file 的末尾, | command 表示把输出写到一个管道中. 类
似的, command | getline 表示把命令 command 的输出以管道的方式输送给 getline. 函数
getline 在遇到文件末尾时返回 0, 出错时返回 -1.
Build-in
variables
Variables | Interpretation |
---|---|
ARGC | 命令行参数的个数 |
ARGV | 命令行参数组成的数组 (ARGV[0..ARGC-1]) |
FILENAME | 当前输入文件的文件名 |
FNR | 当前输入文件已读取的记录个数 |
FS | 输入数据的字段分隔符 (默认是空格) |
NF | 当前输入记录的字段个数 |
NR | 从程序开始到现在, 读取到的记录个数 |
OFMT | 数字的输出格式 (默认是 “%.6g”) |
OFS | 输出字段分隔符 (默认是空格) |
ORS | 输出记录分隔符 (默认是换行符) |
RLENGTH | 被函数 match 中的正则表达式匹配的字符串的长度 |
RS | 输入数据的记录分隔符 (默认是换行符) |
RSTART | 被函数 match 匹配的字符串在原字符串中的开始位置 |
SUBSEP | 具有形式 [i,j,…] 的数组下标的分隔符 (默认是 “\034”) |
ARGC 和 ARGV 包含被执行的程序的名字 (通常是 awk), 但是不包括出现在命令行中的 awk 程序或选
项. RLENGTH 同时也是 match 的返回值.
String Functions
Arithmetic Functions
Functions | Interpretation |
---|---|
atan2(y,cos(x) | y/x 的反正切值, 弧度制, 定义域从 −π 到 π |
exp(x) | 余弦 (弧度制) |
int(x) | 指数 ex |
log(x) | 取整 |
rand() | 自然对数 |
sin(x) | 返回一个伪随机数 r (0 ⩽ r < 1 ) |
x) | 正弦 (弧度制) |
sqrt(x) | 平方根 |
srand(x) | 设置随机数种子, 如果省略 x, 则默认使用当天的时间 |
Regular Expressions
正则表达式的元字符包括: \ ^ $ . [ ] | ( ) * + ?
下面的表格总结了正则表达式及其所匹配的字符串:
Regex | Interpretation |
---|---|
c | 匹配一个非元字符 c |
\c | 匹配一个转义序列, 或一个字面上的字符 c |
ˆ | 匹配一个字符串的开始 |
$ | 匹配一个字符串的结束 |
. | 匹配任意一个字符 |
[ˆabc…] | 字符集合: 匹配 abc… 中的任意一个字符 |
r1 | r2 | 选择: 匹配一个能被 r1 或 r2 匹配的字符串 |
(r1 )(r2 ) | 拼接: 匹配字符串 xy, 其中 x 被 r1 匹配, y 被 r2 匹配 |
(r)* | 匹配 0 个或多个连续出现的被 r 匹配的字符串 |
(r)+ | 匹配 1 个或多个连续出现的被 r 匹配的字符串 |
(r)? | 匹配 0 个或 1 个被 r 匹配的字符串 |
(r) | 组合: 匹配的字符串与 r 所匹配的字符串相同 |
Escape Sequences
Escape | Interpretation |
---|---|
\b | 退格 |
\f | 换页 |
\n | 换行 |
\r | 回车 |
\t | 制表 |
\ddd | 八进制数, ddd 是 1 到 3 个数字, 每个数字的值在 0 到 7 之间 |
\c | 其他字面上的字符 c, 比如 \” 表示 “, \ 表示 \ |
Limits
- 100 个字段
- 每条输入记录 3000 个字符
- 每条输出记录 3000 个字符
- 每个字段 1024 个字符
- 每个 printf 字符串 3000 个字符
- 字面字符串 400 个字符
- 字符集合 400 个字符
- 15 个打开文件, 1 个管道
- 双精度浮点数
数值的限制与本地系统所能表示的数值范围有关, 比如某个机器所能表示的数值范围是 10−38 到 1038 ,超过这个范围的数值只拥有字符串形式.