GAWK命令内建变量的使用

GAWK命令内建变量的使用

1 GAWK程序介绍

gawk程序是awk程序的GNU版本,它能提供一个类编程环境来修改和重新组织文件中的数据,以生成满足特定格式的易于阅读的报告。在现在的centos6和centos7中使用的awk程序实际通过软链接指向了gawk程序。

[root@Centos7T ~]#ll `which awk`
lrwxrwxrwx. 1 root root 4 Jul 14 12:08 /usr/bin/awk -> gawk

我们可以利用gawk的编程能力完成以下功能:

* 定义变量来保存数据;
* 使用算术和字符串操作符来处理数据;
* 使用结构化编程概念(比如if-then语句和循环)来为数据处理增加处理逻辑;
* 通过提取数据文件中的数据元素,将其重新排列或格式化,生成格式化报告。

本文单就gawk程序的内建变量进行简单介绍,而gawk的內建变量又分为两类:

1. 字段和记录分隔符变量
2. 数据变量

2 字段和记录分隔符变量

顾名思义,字段和记录分隔符变量被用来指定分隔符,以分隔需要处理的字段和记录,从而可以方便的提取出我们所需要的数据。gawk程序使用的分隔符变量如下:

FIELDWIDTHS     由空格分隔的一列数字,定义了每个数据字段确切宽度
FS              输入字段分隔符
RS              输入记录分隔符
OFS             输出字段分隔符,默认一个空格
ORS             输出记录分隔符

变量FS指定了一条记录内部各个数据字段的分隔符,这样我们就可以提取指定的字段。而在gawk程序处理输出的各个字段同样可以使用分隔符隔开,已达到格式化输出的目的。针对输出结果的分隔符,我们可以使用变量OFS指定。变量FSOFS的默认值都是空格

[root@Centos7T gawk]#cat t1
data11,data12,data13,data14,data15
data21,data22,data23,data24,data25
data31,data32,data33,data34,data35
[root@Centos7T gawk]#gawk 'BEGIN{FS=","} {print $1,$3,$5}' t1
data11 data13 data15
data21 data23 data25
data31 data33 data35
[root@Centos7T gawk]#gawk 'BEGIN{FS=",";OFS="--"} {print $1,$3,$5}' t1
data11--data13--data15
data21--data23--data25
data31--data33--data35

原始数据都是使用,分隔,在第一次使用gawk程序梳理t1文件的数据时,我们指定FS=",",然后打印每条记录的第1、3、5个字段的数据,而输出分隔符未指定,使用默认的空格将三个数据字段分隔开。在第二次使用gawk程序处理t1文件的数据时,我们指定FS=","OFS="--",然后打印每条记录的第1、3、5个字段的数据,而输出的三个字段将会被--分隔开。

由于gawk程序处理数据是按照一条记录一条记录依次进行的,为了让gawk程序能够按照我们的期望识别各条数据记录,我们需要通过变量RS指定的待处理数据的记录分隔符。多条记录经过gawk程序处理输出的结果同样需要使用分隔符隔开,我们可以使用变量ORS指定。变量RSORS的默认值都是换行符\n

[root@Centos7T gawk]#cat t1-1
data11,data12,data13;data21,data22,data23;data31,data32,data33
[root@Centos7T gawk]#gawk 'BEGIN{FS=","} {print $1,$3}' t1-1
data11 data13;data21
[root@Centos7T gawk]#gawk 'BEGIN{FS=",";RS=";"} {print $1,$3}' t1-1
data11 data13
data21 data23
data31 data33

上述代码分别指定了RS使用默认值和RS=";",两者输出结果对比很明显存在差异性。
变量FIELDWIDTHS设定了一条记录内部各个数据字段的宽度,以此来分隔并识别各个数据字段。变量FIELDWIDTHS规定了将例句分隔成几段,每个字段的宽度,例如FIELDWIDTHS="5 5 2 4"

[root@Centos7T gawk]#cat t1-2
6546845686
6354654687
6574864561
[root@Centos7T gawk]#gawk 'BEGIN{FIELDWIDTHS="3 2 4 1"} {print $1,$2,$3,$4}' t1-2
654 68 4568 6
635 46 5468 7
657 48 6456 1

变量FIELDWIDTHS="3 2 4 1"将每条记录分隔成4个字段,每个字段的宽度分别为3、2、4、1。通过该变量,我们很容易的获取固定列宽度的数据。

3 数据变量

gawk使用的数据变量除了前文我们使用到的诸如$1$2$3$4这样的用于记录中各个提取数据字段的变量,类似于shell脚本的命令行参数(参考我的其他文章:Bash Shell命令行参数的使用)。但不同之处在于$0在命令行参数中表示脚本程序名称,而在gawk程序中,$0存储的是当前gawk程序正在处理的整条记录。

[root@Centos7T gawk]#cat t1-3
How are you
[root@Centos7T gawk]#gawk '{print "$1:",$1,"\n$2:",$2,"\n$3:",$3,"\n$0:",$0}' t1-3
$1: How
$2: are
$3: you
$0: How are you

另外,gawk还有如下常用的内部变量,如下所示:

ARGC          当前命令行参数个数
ARGIND        当前文件在ARGV中的位置
ARGV          包含命令行参数的数组,
ENVIRON       当前shell环境变量及其值组成的关联数组
NF            数据文件中的字段总数
NR            已处理的输入记录数
FNR           当前数据文件中的数据行数
RLENGTH       由match函数所匹配的子字符串的长度
RSTART        由match函数所匹配的子字符串的起始位置

变量ARGCARGINDARGV用于获取gawk的命令行参数,其中变量ARGC可以获取gawk包括程序名本身、需要处理的文件在内的命令行参数的总数;但要注意,程序脚本并不被当做命令行参数。变量ARGV是用于存储命令行参数的数组,ARGV数组从索引0开始,代表的是命令,第一个数组值是gawk命令后的第一个命令行参数。ARGIND用于获取当前正在被gawk程序处理的数据文件名称。如果文件包含路径则一并视为文件名。

[root@Centos7T gawk]#cat file1
This is the first file first line
This is the first file second line
[root@Centos7T gawk]#cat file2
This is the second file first line
This is the second file second line
[root@Centos7T gawk]#gawk '{print ARGC,ARGIND,ARGV[ARGC-1],ARGV[1]}' file1 file2
3 1 file2 file1
3 1 file2 file1
3 2 file2 file1
3 2 file2 file1

在本例中,使用ARGV[ARGC-1]获取最后一个gawk程序的命令行参数。

变量ENVIRON利用关联数组来获取当前shell的环境变量。关联数组ENVIRON的索引应该为shell环境变量的变量名称。例如我们可以利用ENVIRON["HOSTNAME"]来获取当前Shell的hostname。注意,环境变量名应该使用双引号。

[root@Centos7T gawk]#cat t1-3
How are you
[root@Centos7T gawk]#gawk '{print ENVIRON["HOSTNAME"]}' t1-3
Centos7.magedu.com
[root@Centos7T gawk]#gawk '{print ENVIRON["PATH"]}' t1-3
/app/httpd22/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@Centos7T gawk]#gawk '{print ENVIRON["PWD"]}' t1-3
/app/gawk

变量FNRNFNR用于在gawk程序中跟踪数据字段和记录。变量FNR含有当前数据文件中已处理过的记录数;变量NR则含有已处理过的记录总数。二者不同之在于,变量FNR针对当前正在处理的文件。当一个数据文件处理完毕,开始处理下一个文件,例如上面例子中,file1处理完毕开始处理file2,此时变量FNR会被重置为1,而变量NR还会继续计数,不会被重置。而变量NF则含有当前gawk正在处理的数据的字段总数。

[root@Centos7T gawk]#gawk '{print NR,FNR,"the last word is:",$NF}' file1 file2
1 1 the last word is: line
2 2 the last word is: line
3 1 the last word is: line
4 2 the last word is: line

由于变量NF则含有当前gawk正在处理的数据的字段总数,那么可以利用引用数据字段的方式,利用$NF引用当前记录的最后一个字段。

变量RLENGTHRSTART可以配合match函数对匹配到的字符串记录其长度和位置。匹配可以使用指定的字符串、通配符、正则表达式。 match函数的基本格式为match(s,r[,a]),表示在字符串s中匹配rr可以为字符串或者正则表达式,并将匹配结果存储在数组a中。

[root@Centos7T gawk]#gawk 'BEGIN{match("nf38472we30f","we",str);print RSTART,RLENGTH,str[0]}'
8 2 we
[root@Centos7T gawk]#gawk 'BEGIN{match("secure2017-09-17_logfile",/([0-9]+-)+[0-9]+/,date);print RSTART,RLENGTH,date[0]}'
7 10 2017-09-17

在第二个例子中可以很容易的提取其中的日期字符串。至此,关于gawk常用的命令接介绍到这里。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值