1. wiki
awk
可以理解一种编程语言,其对输入数据的每一行都进行文本处理,并内建一些数据结构和函数,在熟悉者手中十分灵活
2. 语法
基本语法框架为,其由选项、脚本和输入的数据等组成
1 | awk [options] '[scripts]' [files] |
1. options
常用的选项主要有 3 个,更多选项可以使用 --help
查看
-f [progfile]
,--file=[progfile]
: 从脚本文件progfile
中读取事先写好的 awk 命令-F [fs]
,--field-separator=[fs]
: 指定输入中的分隔符,fs
可以是字符串或正则表达式,特殊字符可以使用转义-v [var=value]
,--asign=[var=value]
: 给自定义变量赋值,将外部变量传递给 awk
2. scripts
基本语法结构为,脚本通常由模式和命令两部分组成,可以省略其一,但不能同时被省略,其包裹在单引号 ''
或双引号 ""
中。注意,与 shell 的用法一致,在使用单引号 ''
时,变量不会被解释,双引号 ""
中变量则会被替换成相应结果
1 | pattern{commands} |
1. 模式
模式可以是很多种,一般情况下,每碰到一个使模式表达式为真的输入行,命令就会执行
- 正则表达式 : 语法为
/r/
,支持常用的通配符,也可以使用exp ~ /r/
或exp !~ /r/
表达包含和不包含 - 逻辑表达式 : 大于(
>
)、小于(<
)、等于(==
)、且(&&
)、或(||
)、否(!
)等 BEGIN{}
: 特殊模式,其不匹配任何输入行,只在开头执行一次,一般用作变量初始化、打印输表头等操作END{}
: 特殊模式,其不匹配任何输入行,只在结束执行一次,一般用来打印结果等操作
1 | 读取 : 分隔的文件 passwd,取以 root 或 ftp 开头的行,并打印 |
2. 命令
命令支持很多形式,包括变量或数组赋、内置函数、控制流语句等,其格式也有一定要求:
- 一行可包含若干条语句,使用分号分开即可
- 命令的左花括号必须与它的模式在同一行,空行会被忽略
- 注释可以出现在任意一行的末尾,一个注释以井号 (#) 开始,以换行符结束
- 一条长语句可以分散成多行,只要在断行处插入一个反斜杠即可
3. 内建变量
awk 会统计一些元数据信息,并存入内建变量中,常用的有
$0
: 完整的输入记录$n
: 当前记录的由 FS 分隔的第 n 个字段,如 $1 表示第一个字段FS
: 字段分隔符,默认是任一空格NR
: 表示记录数,在执行过程中对应于当前的行号NF
: 表示字段数,在记录被读之后重置为1,如 $NF 为最后一个字段FNR
: 同NR
,但相对于当前文件FILENAME
: 当前输入文件的名
其他变量的详情,可以使用 man awk
来查看,也可以使用命令 awk --dump-variables ''
,会将部分可用的变量输出到 awkvars.out
文件中
ARGC
: 命令行参数的数目。ARGV
: 命令行参数数组ARGIND
: 命令行中当前文件的位置,主要针对多个文件的输入CONVFMT
: 数字转换格式,默认值为%.6g
ERRNO
: 最后一个系统错误的描述FIELDWIDTHS
: 字段宽度列表,用空格分隔FNR
: 同NR
,但相对于当前文件IGNORECASE
: 为真,则进行忽略大小写的匹配,默认为假OFMT
: 数字的输出格式,默认为%.6g
OFS
: 输出字段分隔符,默认为空格ORS
: 输出记录分隔符,默认为换行符RS
: 记录分隔符,默认为换行符RLENGTH
: 由 match 函数所匹配的字符串的长度RSTART
: 由 match 函数所匹配的字符串的第一个位置SUBSEP
: 数组下标分隔符,默认为\034
4. 内建函数
1. 字符串函数
gsub(Ere, Repl, [ In ] )
: 除了正则表达式所有具体值被替代这点,它和 sub 函数完全一样地执行。index(s, t)
: 返回 t 在 s 中出现的位置索引,不存在则返回 0,从 1 开始length ([s])
: 返回字符串 s 的长度,如果没有,则返回整条记录长度($0),数组的话则返回数组元素数量match( String, Ere )
在 String 参数指定的字符串(Ere 参数指定的扩展正则表达式出现在其中)中返回位置(字符形式),从 1 开始编号,或如果 Ere 参数不出现,则返回 0(零)。RSTART 特殊变量设置为返回值。RLENGTH 特殊变量设置为匹配的字符串的长度,或如果未找到任何匹配,则设置为 -1(负一)。split(s, a [, r [, seps]])
: 使用正则表达式 r 将字符串 s 拆分为数组 a 和分隔符数组 seps,并返回字段数。如果 r 省略,则使用 FSsprintf(fmt, expr-list)
: 格式化表达式sub(Ere, Repl, [ In ] )
: 用 Repl 参数指定的字符串替换 In 参数指定的字符串中的由 Ere 参数指定的扩展正则表达式的第一个具体值。sub 函数返回替换的数量。出现在 Repl 参数指定的字符串中的 &(和符号)由 In 参数指定的与 Ere 参数的指定的扩展正则表达式匹配的字符串替换。如果未指定 In 参数,缺省值是整个记录($0 记录变量)。substr(s, i [, n])
: 从字符串 s 的 i 位置开始,返回最多 n 长度的子字符串,如果省略 n,则返回剩下的全部tolower(str)
: 返回将 str 所有字符的小写形式字符串,其与大小写与当前环境有关toupper(str)
: 返回将 str 所有字符的大写形式字符串,其与大小写与当前环境有关
2. 算术函数
atan2(y, x)
: 返回 y/x 的反正切弧度表示cos(expr)
: 弧度的余弦exp(expr)
: 幂函数int(expr)
: 截断至整数的值log(expr)
: 自然对数函数rand()
: 随机数,值域为 [0, 1)sin(expr)
: 弧度的正弦sqrt(expr)
: 平方根函数srand([expr])
: 使用 expr 作为种子的随机函数,如果省略 expr 参数,则使用日期中的天。返回值是先前种子
3. 一般函数
close( Expression )
用同一个带字符串值的 Expression 参数来关闭由 print 或 printf 语句打开的或调用 getline 函数打开的文件或管道。如果文件或管道成功关闭,则返回 0;其它情况下返回非零值。如果打算写一个文件,并稍后在同一个程序中读取文件,则 close 语句是必需的。system(command )
执行 Command 参数指定的命令,并返回退出状态。等同于 system 子例程。Expression | getline [ Variable ]
从来自 Expression 参数指定的命令的输出中通过管道传送的流中读取一个输入记录,并将该记录的值指定给 Variable 参数指定的变量。如果当前未打开将 Expression 参数的值作为其命令名称的流,则创建流。创建的流等同于调用 popen 子例程,此时 Command 参数取 Expression 参数的值且 Mode 参数设置为一个是 r 的值。只要流保留打开且 Expression 参数求得同一个字符串,则对 getline 函数的每次后续调用读取另一个记录。如果未指定 Variable 参数,则 $0 记录变量和 NF 特殊变量设置为从流读取的记录。getline [ Variable ] < Expression
从 Expression 参数指定的文件读取输入的下一个记录,并将 Variable 参数指定的变量设置为该记录的值。只要流保留打开且 Expression 参数对同一个字符串求值,则对 getline 函数的每次后续调用读取另一个记录。如果未指定 Variable 参数,则 $0 记录变量和 NF 特殊变量设置为从流读取的记录。getline [ Variable ]
将 Variable 参数指定的变量设置为从当前输入文件读取的下一个输入记录。如果未指定 Variable 参数,则 $0 记录变量设置为该记录的值,还将设置 NF、NR 和 FNR 特殊变量。