前言

awk变量详解,常用内置变量,自定义变量,内置变量NR NF,内置变量FNR,内置变量RS,内置变量ORS,内置变量FILENAME,内置变量ARGC与ARGV


awk变量

“变量"分为"内置变量” 和 “自定义变量” 。 "输入分隔符FS"和"输出分隔符OFS"都属于内置变量。
内置变量是awk预定义好的、内置在awk内部的变量,而自定义变量就是用户定义的变量。

常用内置变量

awk常用的内置变量以及其作用如下

FS:输入字段分隔符, 默认为空白字符
OFS:输出字段分隔符, 默认为空白字符
RS:输入记录分隔符(输入换行符), 指定输入时的换行符
ORS:输出记录分隔符(输出换行符),输出时用指定符号代替换行符
NF:number of Field,当前行的字段的个数(即当前行被分割成了几列),字段数量
NR:行号,当前处理的文本行的行号。
FNR:各文件分别计数的行号
FILENAME:当前文件名
ARGC:命令行参数的个数
ARGV:数组,保存的是命令行所给定的各参数

例如上一小节讲解的 输入字段分隔符FS, 输出字段分隔符OFS,字段数量NF。

内置变量NR NF

内置变量NR:表示每一行的行号
内置变量NF:表示每一行中一共有几列。

文件中一共有三行文本,使用空格隔开,第1行有3列,第2行有3列 第3行有2列

[root@node1 awkdir]# cat awktxt
zaishu	mysql	qq
xasdf	xxx	sdfsadf
dd	xx
[root@node1 awkdir]# awk '{print NR,NF}' awktxt
1 3 //第一行 32 3
3 2

结合$0打印出整行的内容。

[root@node1 awkdir]# awk '{print NR,$0}' awktxt
1 zaishu	mysql	qq
2 xasdf	xxx	sdfsadf
3 dd	xx

不管是内置变量,还是自定义变量,都不像shell会使用"$",而是直接使用变量名。

内置变量FNR

  • NR处理多个文件

awk处理多个文件的时候,如果使用NR显示行号,那么,多个文件的所有行会按照顺序进行排序。

[root@node1 awkdir]# cat awktxt
zaishu	mysql	qq
xasdf	xxx	sdfsadf
dd	xx
[root@node1 awkdir]# cat awktxt2
abc#123#efg#hij
9ijdd#sdf#asdf#bnm
[root@node1 awkdir]# awk '{print NR,$0}' awktxt awktxt2
1 zaishu	mysql	qq
2 xasdf	xxx	sdfsadf
3 dd	xx
4 abc#123#efg#hij
5 9ijdd#sdf#asdf#bnm
  • FNR处理多个文件

想要分别显示两个文件的行号,可以使用到内置变量FNR。

[root@node1 awkdir]# awk '{print FNR,$0}' awktxt awktxt2
1 zaishu	mysql	qq
2 xasdf	xxx	sdfsadf
3 dd	xx
1 abc#123#efg#hij
2 9ijdd#sdf#asdf#bnm

它的作用就是当awk处理多个文件时,分别对每个文件的行数进行计数。

内置变量RS

RS是输入行分隔符,如果不指定,默认的"行分隔符"就是"回车换行"。

不想以默认的"回车换行"作为"行分隔符",而是想使用空格作为所谓的行分隔符,也就是说,我们想让awk认为,每遇到一个空格,就换行,换句话说,我们想让awk以为每次遇到一个空格就是新的一行。示例如下。

[root@node1 awkdir]# cat awktxt3
asdf wer uoiou sdfl
123 ljk3 9xds
sdf 0knm 8hjlk
  • 默认换行符
[root@node1 awkdir]# awk '{print NR,$0}' awktxt
1 zaishu	mysql	qq
2 xasdf	xxx	sdfsadf
3 dd	xx
  • 使用空格作为换行符
[root@node1 awkdir]# awk -v RS=" " '{print NR,$0}' awktxt3
1 asdf
2 wer
3 uoiou
4 sdfl
123			## 对于awk来说这是一行,都是第四行
5 ljk3
6 9xds
sdf
7 0knm
8 8hjlk

指定使用空格作为"行分隔符"时,在awk解析文本时,每当遇到空格,awk就认为遇到的空格是换行符,于是awk就将文本换行了,而此时之前的"回车换行",对于awk来说并不是所谓的换行符,所以才会出现上图中第4和第6行的现象,但是在awk里,它就是一行。

内置变量ORS

默认情况下"回车换行"当做输出行分隔符
现在,让awk认为,"++"才是真正的输出行分隔符,示例如下图
3. awk变量详解,常用内置变量,自定义变量,内置变量NR NF,内置变量FNR,内置变量RS,内置变量ORS,内置变量FILENAME,内置变量ARGC与ARGV_bash
这个时候输出换行符换成了++ 。

  • "输入换行符"和"输出换行符"同时使用,看看是什么效果,示例如下。
[root@node1 awkdir]# awk -v RS=" " -v ORS="++" '{print NR,$0}' awktxt3
1 asdf++2 wer++3 uoiou++4 sdfl
123++5 ljk3++6 9xds
sdf++7 0knm++8 8hjlk
++[root@node1 awkdir]# 

遇到一个空格表示一行。进行输出的时候换行符换成了++

内置变量FILENAME

FILENAME这个内置变量,显示文件名

[root@node1 awkdir]# awk '{print FILENAME,FNR,$0}' awktxt awktxt2
awktxt 1 zaishu	mysql	qq
awktxt 2 xasdf	xxx	sdfsadf
awktxt 3 dd	xx
awktxt2 1 abc#123#efg#hij
awktxt2 2 9ijdd#sdf#asdf#bnm

内置变量ARGC与ARGV

ARGC内置变量:表示命令行参数的个数。
ARGV内置变量:表示一个数组,这个数组中保存的是命令行所给定的参数。

[root@node1 awkdir]# awk 'BEGIN{print "aa"}' awktxt awktxt2
aa
[root@node1 awkdir]# awk 'BEGIN{print "aa",ARGV[1]}' awktxt awktxt2
aa awktxt
[root@node1 awkdir]# awk 'BEGIN{print "aa",ARGV[1],ARGV[2]}' awktxt awktxt2
aa awktxt awktxt2

使用BEGIN模式,输出一个字符串"aa",然后,传入两个文件的文件名作为参数, BEGIN模式正常执行了打印操作,输出了"aa"字符串,还打印ARGV这个数组中的第二个和第三个元素的值。
ARGV内置变量表示的是一个数组,既然是数组,就需要用上图中的下标的方式,引用对应元素的值,因为数组的索引都是从0开始的,所以,ARGV[1]表示引用ARGV数组中的第二个元素的值, ARGV[2]的值,发现ARGV[2]对应的值为awktxt2,RGV内置变量表示的是:所有参数组成的数组。

ARGV[0]对应的是第一个参数,也就是awk命令本身。awk就是规定’pattern{ action }'并不被看做是参数,awk被看做为参数。

[root@node1 awkdir]# awk 'BEGIN{print "aa",ARGV[0],ARGV[1],ARGV[2]}' awktxt awktxt2
aa awk awktxt awktxt2

在刚才的例子中,应该有三个参数,awk、awktxt1、awktxt2,这三个参数作为数组的元素存放于ARGV中,现在,而ARGC则表示参数的数量,也可以理解为ARGV数组的长度。示例如下

[root@node1 awkdir]# awk 'BEGIN{print "aa",ARGV[0],ARGV[1],ARGC}' awktxt awktxt2
aa awk awktxt 3

自定义变量

自定义变量,顾名思义,就是用户定义的变量,有两种方法可以自定义变量。
方法一:-v varname=value 变量名区分字符大小写。
方法二:在program中直接定义。

  • 方法一自定义变量。
[root@node1 awkdir]# awk -v myVar="testVar" 'BEGIN{print myVar}'
testVar

这种方法还有一个优势,需要在awk中引用shell中的变量的时候,则可以通过方法一间接的引用。如下

[root@node1 awkdir]# var=6666
[root@node1 awkdir]# awk -v myvar=$var 'BEGIN{print myvar}'
6666
  • 使用方法二自定义变量,直接在program中定义即可
    注意:变量定义与动作之间需要用分号";"隔开。
[root@node1 awkdir]# awk   'BEGIN{ myVar="testVar"; print myVar}'
testVar

一次性定义多个变量

[root@node1 awkdir]# awk   'BEGIN{ myVar1="Var1"; myVar2="Var2"; print myVar1,myVar2}'
Var1 Var2

总结

awk变量详解,常用内置变量,自定义变量,内置变量NR NF,内置变量FNR,内置变量RS,内置变量ORS,内置变量FILENAME,内置变量ARGC与ARGV