一、数值变量和字符串变量
数值常量可以表示为整数(如243)、浮点数(如3.14)或用科学计数法表示的数(如。723E-1或3.4e7)。字符串则括在双引号中,例如“Hello world”。
初始化与强制类型转换 只要在 awk 程序中被提到,变量就开始存在。变量可以是一个字符串或一个数字,也可以既是字符串又是数字。变量被设置后,就变成与等号右边那个表达式相同的类型。
未经初始化的变量的值是 0 或 “”,究竟是哪个取决于它们被使用时的上下文。
name = "Nancy" # name 是字符串
x++ # x 是数字,它被初始化为0,然后加1
number = 35 # number 是数字
如果要将一个字符串强制转换为数字,方法为:
name + 0
将数字转换成字符串的方法则是:
number" "
二、awk 内置变量
内置变量的名字都适合大写的。它们可以被用于表达式,也可以被重置。如下表:
变量名 | 含义 |
---|---|
ARGC | 命令行参数的数目 |
ARGV | 命令行参数构成的数组 |
CONVFMT | 数字转换格式,默认为 %.6g |
ENVIRON | 包含当前 shell 环境变量值的数组 |
FILENAME | 当前输入文件的文件名 |
FNR | 当前文件的记录数 |
IGNORECASE | 在正则表达式和字符串匹配中不区分大小写 |
NF | 当前记录中的字段数 |
NR | 目前的记录数 |
OFMT | 数字的输出格式 |
OFS | 输出字段分隔符 |
ORS | 输出记录分隔符 |
RS | 输入记录分隔符 |
SUBSEP | 数组下标分隔符 |
-F 选项用来在命令行重新设置输入字符分隔符的值。当冒号紧跟在 -F 选项的后面时,awk 就会在文件中查找冒号,用以分隔字段。 |
awk -F: '{print $1}' test.log
**使用多个字段分隔符** 你可以指定多个输入字段分隔符。如果有多个字符被用于字段分隔符 FS,则 FS 对应是一个正则表达式字符串,并且被括在方括号中。下面的范例中,字段分隔符是空格、冒号或制表符。
awk -F'[ :\t]' '{print $1}' test.log
-F 选项后面跟了一个位于方括号中的正则表达式。当遇到空格、冒号或制表符时,awk 会把它当成字段分隔符。这个表达式两头加了引号,这样就不会被 shell 当成自己的元字符来解释(注意, shell 使用方括号来进行文件名扩展)。
三、模式与操作
模式
awk 模式用来控制 awk对输入的文本行执行什么操作。模式由正则表达式、判别条件真伪的表达式或二者的组合构成。awk 的默认操作是打印所有使表达式结果为真的文本行。模式表达式中暗含着 if 语句。如果模式表达式含有 if(如果)的意思,就不必用花括号把它括起来。当 if 是显式地给出时,这个表达式就成了操作语句,语法将不一样。
1. awk '/Tom/' test.log
2. awk '$3 < 4000' test.log
说明
1.如果在输入文件中匹配到模式Tom,则打印Tom所在的记录。如果没有显式地指定操作,默认操作是打印文本行,等价于命令:
awk '$0 ~ /Tom/ {print $0}' test.log
- 如果第 3 个字段的值小于 4000,则打印该记录。
操作
操作(action)是花括号中以分号分隔的语句。如果操作前面有个模式,则该模式控制执行操作的时间。操作可以是简单的语句或复杂的语句组。同一行内的多条语句由分号分隔,独占一行的语句则以换行符分隔。
格式
模式 {操作语句; 操作语句; ....; }
或
模式 {
操作语句
操作语句
}
四、正则表达式
对 awk 而言,正则表达式是置于两个正斜杠之间、由字符组成的模式。awk 支持使用(与egrep相同的)正则表达式元字符会正则表达式进行某种方式的修改。如果输入行中的某个字符串与正则表达式匹配,则条件为真,于是执行与该表达式关联的所有操作。
awk '/Mary/' test.log
awk '/Mary/ {print $1, $2}' test.log
awk的正则表达式元字符
元字符 | 说明 |
---|---|
^ | 在串首匹配 |
$ | 在串尾匹配 |
. | 匹配单个任意字符 |
* | 匹配零个或多个前导字符 |
+ | 匹配一个或多个前导字符 |
? | 匹配零个或一个前导字符 |
[ABC] | 匹配指定字符组中任一字符 |
[^ABC] | 匹配任何一个不在指定字符组中的字符 |
[A-Z] | 匹配A至Z之间的任一字符 |
AB | 匹配A或B |
(AB)+ | 匹配一个或多个AB的组合,例如:AB、ABAB、ABABAB |
* | 匹配星号本身 |
& | 用在替代串中,代表查找串中匹配到的内容 |
匹配操作符(~)用于对记录或字段的表达式进行匹配。
1. awk '$1 ~ /[Bb]ill/' test.log
2. awk '$1 !~ /ly$/' test.log
说明
1、显示所有在第一个字段里匹配到 Bill 或 bill 的行。
2、显示所有第一个字段不是以 ly 结尾的行。
POSIX 字符类
POSIX是一种工业标准,确保程序可以跨操作系统移植。下表对括号字符类进行了说明
POSIX 增加的括号字符类
括号类 | 含义 |
---|---|
[:alnum:] | 字母数字字符 |
[:alpha:] | 字母字符 |
[:cntrl:] | 控制字符 |
[:digit:] | 数字字符 |
[:graph:] | 非空白字符(非空格、控制字符等) |
[:lower:] | 小写字母 |
[:print:] | 与[:graph:]相似,但是包含空格字符 |
[:punct:] | 标点字符 |
[:space:] | 所有的空白字符(换行符、空格、制表符) |
[:upper:] | 大写字母 |
[:xdigit:] | 允许十六进制的数字(0-9a-fA-F) |
五、BEGIN/END模式
BEGIN模式后面跟了一个操作块。awk 必须在对输入文件进行任何处理之前先执行该操作块。实际上,不需要任何输入文件,也能对BEGIN块进行测试,因为 awk 要在执行完 BEGIN 操作块后才开始读取输入。BEGIN 操作常常被用于修改内置变量(OFS、RS、FS等)的值、为用户自定义变量赋初值和打印输出的页眉或标题。
awk 'BEGIN{FS=":"; OFS="\t"; ORS="\n\n"} {print $1, $2, $3}' file
说明
在处理输入文件之前,awk 先把字段分隔符(FS)设为冒号,把输出分割符(OFS)设为制表符,还把输出记录分隔符(ORS)设为两个换行符。如果BEGIN的操作块中有两条或两条以上语句,必须用分号分隔它们或每行只写一条语句。
END模式不匹配任何输入行,而是执行任何与之关联的操作。awk 处理完所有输入行之后才处理END模式。
awk 'END{print "The number of records is " NR}' file
awk 处理完整个文件后才开始执行END块。此时NR的值是最后这条记录的记录号。
awk '/Mary/{count++}END{print "Mary was found " count " times."}' file
每遇到一个包含模式 Mary 的行,用户自定义的变量 count 的值就加1。 awk 处理完整个文件后,END块打印字符串 Mary was found ,再跟上变量 count 的值和字符串 times。