shell awk 内置变量、正则表达式、BEGIN/END模式


一、数值变量和字符串变量

数值常量可以表示为整数(如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
  1. 如果第 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。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值