BEGIN和END关键字是来用来读取数据流之前或之后执行命令的特殊模式
1、内建变量
FIELDWIDTHS:由空格分隔开的的定义每个数据字段确切宽度的一列数字
FS:输入字段分隔符
RS:输入数据行分隔符
OFS:输出字段分隔符
ORS:输出数据行分隔符
[root@node3 conf]# cat data2 data1,data2,data3,data4,data5 data6,data7,data8,data9,data10 data11,data12,data13,data14,data15
[root@node3 conf]# gawk 'BEGIN{FS=",";OFS="-"} {print $1,$2,$3}' data2 data1-data2-data3 data6-data7-data8 data11-data12-data13
数据流占多行情况下
把RS变量设置成空白字符串,然后在数据行间留一个空白行。gawk会把每个空白行当作一个数据行分隔符
[root@node3 conf]# cat data3 Tom Mullen 123 Main Street Chicago.IL 6001 (312)555-1234 Frank Williams 456 Oak street Indianpolis.IN 46201 (317)55-9786
[root@node3 conf]# gawk 'BEGIN{FS="\n";RS=""} {print $1,$4}' data3 Tom Mullen (312)555-1234 Frank Williams (317)55-9786
2、数据变量
FNR:当前数据文件中的数据行数
NF:数据文件中的字段总数
NR:已处理的输入数据行数目
[root@node3 conf]# gawk 'BEGIN{FS=":";OFS=";"}{print $1,$NF}' /etc/passwd root;/bin/bash bin;/sbin/nologin daemon;/sbin/nologin adm;/sbin/nologin lp;/sbin/nologin
[root@node3 conf]# cat data2 data1,data2,data3,data4,data5 data6,data7,data8,data9,data10 data11,data12,data13,data14,data15 [root@node3 conf]# gawk ' BEGIN{FS=","} {print $1,"FNR="FNR,"NR="NR} END{print "there were",NR,"records processed"}' data2 data2 data1 FNR=1 NR=1 data6 FNR=2 NR=2 data11 FNR=3 NR=3 data1 FNR=1 NR=4 data6 FNR=2 NR=5 data11 FNR=3 NR=6 there were 6 records processed
3、自定义变量
变量名不能以数字开头,
[root@node3 conf]# gawk ' > BEGIN{ > testing="this is a test" > print testing > }' this is a test
[root@node3 conf]# gawk 'BEGIN{X=4;X=X*2+3;print X}' 11
在命令行上给变量赋值
[root@logicserver tmp]# cat script1 #!/bin/bash # BEGIN{FS=","} {print $n} [root@logicserver tmp]# cat data3 data1,data2,data3,data4,data5 data6,data7,data8,data9,data10 data11,data12,data13,data14,data15 [root@logicserver tmp]# gawk -f script1 n=2 data3 data2 data7 data12
在设置变量后,这个值在代码的BEGINU部分不可用
[root@logicserver tmp]# vim script1 #!/bin/bash # BEGIN{print "the starting value is ",n;FS=","} {print $n}
[root@logicserver tmp]# gawk -f script1 n=3 data3 the starting value is data3 data8 data13
加上-v,允许你指定BEGIN代码部分之前设定的变量
[root@logicserver tmp]# gawk -f script1 -v n=3 data3 the starting value is 3 data3 data8 data13
4、遍历数组
for (var in array)
{
statements
}
for语句在每次将关联数组array的下一个索引值赋给变量var时,执行一遍statements。
记住这个变量是索引值而不是数组元素的值
[root@logicserver tmp]# gawk 'BEGIN{ var["a"]=1 var["g"]=2 var["m"]=3 var["u"]=4 for (test in var) { print "Index:",test," - Valuse:",var[test] } }' Index: u - Valuse: 4 Index: m - Valuse: 3 Index: a - Valuse: 1 Index: g - Valuse: 2
删除数组的变量
从关联数组中删除数组索引要用一个特别命令
delete array[index]
[root@logicserver tmp]# gawk 'BEGIN{ var["a"]=1 var["g"]=2 for (test in var) { print "Index:",test,"- Value",var[test] } delete var["g"] print "------------" for (test in var) { print "Index:",test,"- Value",var[test] } > }' Index: a - Value 1 Index: g - Value 2 ------------ Index: a - Value 1
5、匹配操作符
匹配操作符(~),允许将正则表达式限定在数据行中的特定数据字段。
$1 ~/expression/
用正则表达式/^data2/来匹配第二个数据段,过滤第二个字段以文本data2为开头的行
[root@logicserver tmp]# cat data3 data1,data2,data3,data4,data5 data6,data7,data8,data9,data10 data11,data12,data13,data14,data15 data21,data22,data23,data24,data25 [root@logicserver tmp]# gawk 'BEGIN{FS=","} $2 ~/[^data2]/{print $0}' data3 data6,data7,data8,data9,data10 data11,data12,data13,data14,data15
gawk程序脚本常用在数据文件查找特定数据元素的强大工具
[root@logicserver tmp]# gawk -F: '$1 ~/root/{print $1,$NF}' /etc/passwd root /bin/bash
用!符号来排除正则表达式的匹配
$1 !~/expression/
gawk -F: '$1 !~/root/{print $1,$NF}' /etc/passwd
6、数学表达式
x == y
x <= y
x < y
x >= y
x > y
如显示所有属于root用户组的(组ID为0)的系统用户
[root@logicserver tmp]# gawk -F: '$4==0{print $1}' /etc/passwd root sync shutdown halt operator
对文本数据使用表达式,必须要小心,跟正则表达式不同,表达式必须完全匹配
[root@logicserver tmp]# gawk -F, '$1== "data1" {print $1}' data3 data1
6、if语句
if (condition)
statement1
或者 if (condition) statement1
[root@logicserver tmp]# cat data4 10 5 3 13 55 [root@logicserver tmp]# gawk '{if ($1>20) print $1}' data4 55
[root@logicserver tmp]# gawk '{ > if ($1>20) > { > x=$1 * 2 > print x > } > }' data4 110
gawk的if语句也支持else子句,允许在if语句条件不成立的情况下执行一条或多条语句。
[root@logicserver tmp]# gawk '{ > if ($1>100) > { > x=$1 * 2 > print x > } else > { > x=$1 / 2 > print x > }}' data4 5 2.5 1.5 6.5 27.5
也可以这么写
if (condition) statement1:else statement2
[root@logicserver tmp]# gawk '{if ($1>100) print $1*2;else print $1/2}' data4 5 2.5 1.5 6.5 27.5
7、while语句
while (condition)
{
statement1
}
[root@logicserver tmp]# cat data5 120 130 135 160 113 140 145 170 215 [root@logicserver tmp]# gawk '{ total=0 i=1 while (i<4) { total+=$i i++ } avg=total/3 print "Averaget:",avg }' data5 Averaget: 128.333 Averaget: 137.667 Averaget: 176.667 Averaget: 0
8、do-while语句
do
{
statement1
} while (condition)
[root@logicserver tmp]# gawk '{ total=0 i=1 do { total+=$i i++ }while (total<150) print total}' data5 250 160 315
9、for语句
for (variable assignment;condition;interation process)
[root@logicserver tmp]# gawk '{ > tatal=0 > for (i=1;i<4;i++) > { > total+=$i > } > avg=total/3 > print "Average:",avg > }' data5 Average: 128.333 Average: 266 Average: 442.667 Average: 442.667 [root@logicserver tmp]# gawk '{for (i=1;i<4;i++) total+=$i;avg=total/3;print "Average:",avg}' data5 Average: 128.333 Average: 266 Average: 442.667 Average: 442.667 [root@logicserver tmp]# cat data5 120 130 135 160 113 140 145 170 215
10、格式化打印
在printf命令末尾手动添加换行符来生成新行
如果需要几个单独的printf命令来在同一行上打印多个输出
[root@logicserver tmp]# cat data3 data1,data2,data3,data4,data5 data6,data7,data8,data9,data10 data11,data12,data13,data14,data15 data21,data22,data23,data24,data25 [root@logicserver tmp]# gawk 'BEGIN{FS=","}{printf "%s ",$1}END{printf "\n"}' data3 data1 data6 data11 data21
[root@logicserver tmp]# gawk 'BEGIN{FS=","}{printf "%s ",$1}' data3 data1 data6 data11 data21 [root@logicserver tmp]#