awk的内部变量的个数不多,在这里介绍的时候就不按照字母顺序排列了,而是按相关性分类说明。
ARGC ARGC表示命令行上除了选项-F,-v,-f等选项及其所对应的参数之外的所有参数的个数。如果将“awk程序”直接写在命令行上,那么ARGC是不会把“awk程序”计算在内的。
ARGV ARGV是一个数据,用来记录命令行上的参数的名称。 执行下列命令:[root@myfreelinux pub]# awk ‘BEGIN{printf(“ARGC=%d/n”,ARGC);for(a in ARGV)printf(“ARGV[%d]=%s/n”,a,ARGV[a]);}’ inte integerARGC=3ARGV[0]=awkARGV[1]=inteARGV[2]=integer 需要注意当ARGC = 3 时,命令列上只指定了2 个文件。awk的参数-F/t 表示以tab 为栏位分隔字符FS(field seporator);-v a=8 是用以初始化程序中的变量。 FILENAME FILENAME用来表示目前正在处理的文件名。
FS域分隔字符 $0 表示目前awk所读入的数据行的内容,$1,$2…示所读入的数据行经过FS指定分割符分割后的第一域,第二域…的记过。 说明:当awk读入一行数据行”A123 8:15″ 时,会先以$0 记录,即$0 = “A123 8:15″,如果程序中进一步使用了$1,$2…或 NF等内部变量时,awk才会自动分割 $0,以便取得各域的数据。 切割后各个域的数据会分別用$1,$2, $3…等存储。 awk默认的(default)域分隔字符(FS)为空白字符(空格及tab)。以上例来说,如果没有改变FS的值,那么分割后:第一个域($1)=”A123″,第二个域($2)=”8:15″。也可以使用正则表达式来定义FS,比如FS=/[ /t:]+/,表示0或多个空格、tab、:分别或他们三个任意组合成的字符串作为分割符,awk每次需要分割数据行时,就会参考目前FS的值。 那么这定FS后,$0 = “A123 8:15″,将被分割为,第一个域($1) = “A123″,第二个域($2) = “8″,第三个域($3) = “15″。
NR (number record) NR表示awk 开始执行该程序后所读取的数据行数。
FNR (file number record) FNR 与NR功用类似;不同的是awk在处理多个数据文件的时候,每打开一个新的文件,FNR便从0重新累计,而NR是一直累加,看个列子更直观些,见下列:
[root@myfreelinux pub]# cat inte123324[root@myfreelinux pub]# cat integer222 111333 111
444 111[root@myfreelinux pub]# awk ‘BEGIN{print NR,FNR,$0}’ inte integer0 0[root@myfreelinux pub]# awk ‘{print NR,FNR,$0}’ inte integer1 1 1232 2 3243 1 222 1114 2 333 1115 36 4 444 111
NF (number field) NF表示当前行被域分隔符分割成的域的个数。awk 每读入一笔数据后,在程序中用NF记录该行数据包含的域的个数。在下一行数据被读入之前,NF不会改变。但如果使用$0来记录数据,例如:使用getline,此时NF将代表新的$0上数据的域的个数。
OFS (output file separate) OFS输出域分隔字符。默认是” “(一个空白)
ORS (output Record separate) ORS输出数据行分隔字符。默认值是”/n”(换行符)。
OFMT(output format) OFMT数值数据的输出格式。默认值”%.6g”(若须要时最多印出6位小数)。
当使用print指令一次打印出多项数据时,例如:print $1,$2,输出时,awk会自动在$1与$2之间补上一个域分隔符的值(OFS 之值);每次使用print输出后,awk会自动补上h行分隔符的值(ORS 之值)。使用print 输出数值数据时,awk将采用 OFMT 之值为输出格式。例如:[root@myfreelinux pub]# awk ‘BEGIN{print 2/3;OFS=”:”;OFMT=”%.2g”;print 2/3,1;}’0.6666670.67:1 程序中通过改变OFS和OFMT的值,改变了指令print的输出格式。
RS RS( Record Separator) :awk从文件上读取数据时,将根据RS的定义把数据切割成许多Records,awk一次只读入一个Record进行处理。RS 的默认值是换行符”/n”,所以一般awk一次仅读入一行数据。有时一个Record含括了几行数据(Multi-line Record),这情況下不能再以”/n” 来分隔相邻的Records,可改用空白行来分隔,即令RS = “”,表示以空白行来分隔相邻的Records。
RSTART RSTART与使用字串函数match( )有关的变量,是匹配的字符的开始的位置。 RLENGTH RLENGTH与使用字串函数match( )有关的变量,RLENGTH是匹配的字符串的长度。当使用match() 函数后,awk会将match() 执行的结果以RSTART和RLENGTH记录。看下面的例子:[root@myfreelinux pub]# awk ‘BEGIN{match(“banana”,”an”);print RSTART,RLENGTH}’2 2[root@myfreelinux pub]# awk ‘BEGIN{match(“banana”,/(an)+/);print RSTART,RLENGTH}’2 4[root@myfreelinux pub]# awk ‘BEGIN{match(“banana”,/(na)+/);print RSTART,RLENGTH;}’3 4
SUBSEP SUBSEP(Subscript Separator) 数组下标的分隔字符,默认值为”/034″实际上,awk中的数组只接受字串当它的下标,比如: Arr["John"]。但awk中仍然可使用数字当数组的下标,甚至可使用多维的数组(Multi-dimenisional Array),比 如:Arr[2,20]。事实上,awk在接受Arr[2,20]之前,就已先把其下标转换成字串”2/03420″,之后便以Arr["2/03420"] 代替Arr[2,20]。可参考下例:[root@myfreelinux pub]# awk ‘BEGIN{arr[2,20]=13;print arr[2,20];print arr["2/03420"];idx=2 SUBSEP 20;print arr[idx];}’131313 再看下面这个例子,统计每门课有几个学生选修,用课程名称作为数组的下标:[root@myfreelinux pub]# cat kecheng.datzhangsan math english chineselisi computer chinese englishwangwu dianzi chinese mathzhaoliu huanjing english chinese[root@myfreelinux pub]# cat kecheng.awk#!/bin/awk -f{for(i=2;i<=NF;i++) array[$i]++;}END{for(one_array in array) print one_array,array[one_array];}[root@myfreelinux pub]# awk -f kecheng.awk kecheng.datcomputer 1english 3dianzi 1chinese 4math 2huanjing 1