一、使用变量
gawk支持两种不同类型的变量:
- 内建变量
- 自定义变量
1.1 内建变量
①字段和记录分隔符变量
FIELDWIDTHS:有空格分割的一列数字,定义了每个数据字段确切宽度
- FS:输入字段分隔符
- RS:输入记录分隔符
- OFS:输出字段分隔符
- ORS:输出记录分隔符
chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{FS=","; OFS="-"} {print $1,$2,$3}' data1 data11-data12-data13 data21-data22-data23 data31-data32-data33 chen@ubuntu:~/shell/ch22$ cat data1 data11,data12,data13,data14,data15 data21,data22,data23,data24,data25 data31,data32,data33,data34,data35 chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{FS=","; OFS="--"} {print $1,$2,$3}' data1 data11--data12--data13 data21--data22--data23 data31--data32--data33 chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{FS=","; OFS="<-->"} {print $1,$2,$3}' data1 data11<-->data12<-->data13 data21<-->data22<-->data23 data31<-->data32<-->data33 cat data1b 1005.3247596.37 115-2.349194.00 05180.1298100.1 chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{FIELDWIDTHS="3 5 2 5"}{print $1,$2,$3,$4}' data1b 100 5.324 75 96.37 115 -2.34 91 94.00 051 80.12 98 100.1 chen@ubuntu:~/shell/ch22$ cat data2 Riley Mullen 123 Main Street Chicago, IL 60601 (312)555-1234 Frank Williams 456 Oak Street Indianapolis, IN 46201 (317)555-9876 Haley Snell 4231 Elm Street Detroit, MI 48201 (313)555-4938 chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{FS=" "; RS=""}{print $1,$4}' data2 Riley Mullen (312)555-1234 Frank Williams (317)555-9876 Haley Snell (313)555-4938 #把换行符变成字段分隔符,把空行当做一个字段分隔符
②数据变量
- ARGC:当前命令行参数个数
- ARGIND:当前文件在ARGV中的位置
- ARGV:包含命令行参数的数组
- CONVFMT:数字的转换格式
- ENVIRON:当前shell环境变量及其值组成的关联数组
- ERRNO:当读取或闭输入文件发生错误时的系统错误号
- FILENAME:用作gawk输入数据的数据文件的文件名
- FNR:当前数据文件中的数据行数
- IGNORECASE:设成非零值时,忽略gawk命令中出现的字符串的字符大小写
- NF:数据文件中的字段总数
- NR:已处理的输入记录数
- OFMT:数字的输出格式,默认值为%.6g
- RLENGTH:由match函数所匹配的子字符串的长度
- RSTART:由match函数所匹配的子字符串的起始位置
chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{print ARGC,ARGV[1]}' data1 2 data1 chen@ubuntu:~/shell/ch22$ cat data1 data11,data12,data13,data14,data15 data21,data22,data23,data24,data25 data31,data32,data33,data34,data35 chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{print ARGC,ARGV[0]}' data1 2 gawk chen@ubuntu:~/shell/ch22$ gawk ' > BEGIN{ > print ENVIRON["HOME"] > print ENVIRON["PATH"] > }' /home/chen /home/chen/bin:/home/chen/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{FS=":"; OFS=":"} {print $1,$NF}' /etc/passwd root:/bin/bash daemon:/usr/sbin/nologin bin:/usr/sbin/nologin sys:/usr/sbin/nologin chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{FS=","}{print $1,"FNR="FNR}' data1 data1 data11 FNR=1 data21 FNR=2 data31 FNR=3 data11 FNR=1 data21 FNR=2 data31 FNR=3 chen@ubuntu:~/shell/ch22$ cat data1 data11,data12,data13,data14,data15 data21,data22,data23,data24,data25 data31,data32,data33,data34,data35
1.2 自定义变量
gawk自定义变量名可以是任意数目的字母、数字和下划线。gawk变量名区分大小写。
①在脚本中给变量赋值
chen@ubuntu:~/shell/ch22$ gawk ' > BEGIN{ > testing="This is a test" > print testing > }' This is a test chen@ubuntu:~/shell/ch22$ gawk ' > BEGIN{ > testing="This is a test" > print testing > testing=45 > print testing > }' This is a test 45 chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{x=4; x= x * 2 + 3; print x}' 11
②在命令行上给变量赋值
chen@ubuntu:~/shell/ch22$ cat script1 BEGIN{FS=","} {print $n} chen@ubuntu:~/shell/ch22$ gawk -f script1 n=2 data1 data12 data22 data32 chen@ubuntu:~/shell/ch22$ gawk -f script1 n=3 data1 data13 data23 data33 chen@ubuntu:~/shell/ch22$ gawk -f script2 n=3 data1 The starting value is data13 data23 data33 chen@ubuntu:~/shell/ch22$ cat script2 BEGIN{print "The starting value is",n; FS=","} {print $n} chen@ubuntu:~/shell/ch22$ gawk -v n=3 -f script2 data1 The starting value is 3 data13 data23 data33
二、处理数组
2.1 定义数组变量
数组变量赋值的格式如下:
var[index] = element
其中var是变量,index是关联数组的索引值,element是数据元素
chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{ > capital["Illinois"] = "Springfield" > print capital["Illinois"] > }' Springfield chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{ > var[1] = 34 > var[2] = 3 > total = var[1] + var[2] > print total > }' 37
2.2 遍历数组变量
gawk中遍历数组,用一种for的特殊形式
for ( var in array ) { statements }
使用例子:
chen@ubuntu:~/shell/ch22$ gawk 'BEGIN{ var["a"] = 1 var["g"] = 2 var["m"] = 3 var["u"] = 4 for ( test in var) { print "Index:",test," - Value:",var[test] } }' Index: u - Value: 4 Index: m - Value: 3 Index: a - Value: 1 Index: g - Value: 2
2.3 删除数组变量
从关联数组中删除数组索引要用一个特殊的命令。
delete array[index]
删除命令会从数组中删除关联索引值和相关的数据元素值
chen@ubuntu:~/shell/ch22$ 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
三、使用模式
本节将会演示如何在gawk脚本中用匹配模式来限定程序脚本作用在哪些记录上。
3.1 正则表达式
在使用正则表达式时,正则表达式必须出现在它要控制的程序脚本的左花括号前。
myfly2@ubuntu:~$ cat data1 data11,data12,data13,data14,data15 data21,data22,data23,data24,data25 data31,data32,data33,data34,data35 myfly2@ubuntu:~$ awk 'BEGIN{FS=","} /11/{print $1}' data1 data11 myfly2@ubuntu:~$ awk 'BEGIN{FS=","} /,d/{print $1}' data1 data11 data21 data31
3.2 匹配操作符
匹配操作符:允许将正则表达式限定在记录中的特定数据字段。
匹配操作符是波浪线(~)。可以指定匹配操作符、数据字段变量以及要匹配的正则表达式。
$1 ~ /^data/
$1:代表记录中的第一个数据字段。这个表达式会过滤出第一个字段以文本data开头的所有记录。
myfly2@ubuntu:~$ awk 'BEGIN{FS=","} $2 ~ /^data2/{print $0}' data1 data21,data22,data23,data24,data25 myfly2@ubuntu:~$ awk -F: '$1 ~ /myfly/{print $1,$NF}' /etc/passwd myfly2 /bin/bash
$1 !~ /expression/
myfly2@ubuntu:~$ awk -F: '$1 !~ /myfly2/{print $1,$NF}' /etc/passwd root /bin/bash daemon /usr/sbin/nologin bin /usr/sbin/nologin sys /usr/sbin/nologin sync /bin/sync games /usr/sbin/nologin man /usr/sbin/nologin lp /usr/sbin/nologin
3.3 数学表达式
除了正则表达式,也可以在匹配模式中用数学表达式。 常用的表达式:
- x == y:值x等于y
- x <= y:值x小于等于y
- x < y:值x小于y
- x >= y:值x大于等于y
- x > y:值x大于y
myfly2@ubuntu:~$ awk -F: '$4 == 0{print $1}' /etc/passwd root myfly2@ubuntu:~$ awk -F, '$1 == "data"{print $1}' data1 myfly2@ubuntu:~$ cat data1 data11,data12,data13,data14,data15 data21,data22,data23,data24,data25 data31,data32,data33,data34,data35 myfly2@ubuntu:~$ awk -F, '$1 == "data11"{print $1}' data1 data11 #与正则表达式不同,数学表达式必须完全匹配
四、结构化命令
4.1 if语句
gawk支持标准的if-then-else格式的if语句。
格式: if (condition)
statement1
也可以这样:if (condition) statement1
awk '{if ($1 > 20) print $1}' data4 50 34 myfly2@ubuntu:~/shell/ch22$ awk '{ > if ($1 > 20) > { > x = $1 * 2 > print x > } > }' data4 100 68
4.2 while语句
基本循环的格式:
while (condition)
{
statement1
}
myfly2@ubuntu:~/shell/ch22$ awk '{ total = 0 i = 1 while (i<4) { total += $i i++ } avg = total / 3 print "Average:",avg }' data5 Average: 128.333 Average: 137.667 Average: 176.667 myfly2@ubuntu:~/shell/ch22$ awk '{ > total = 0 > i = 1 > while (i<4) > { > total += $i > if(i == 2) > break > i++ > } > avg = total /2 > print "The average of the first two data elements is:",avg > }' data5 The average of the first two data elements is: 125 The average of the first two data elements is: 136.5 The average of the first two data elements is: 157.5
4.3 do-while语句
格式:
do
{
statements
}
myfly2@ubuntu:~/shell/ch22$ awk '{ > total = 0 > i = 1 > do > { > total += $i > i++ > } > while (total < 150) > print total }' data5 250 160 315
4.4 for语句
格式:for( variable assignment; condition; iteration process)
myfly2@ubuntu:~/shell/ch22$ awk '{ > total = 0 > for(i=1;i<4;i++) > { > total += $i > } > avg = total / 3 > print "Average:",avg > }' data5 Average: 128.333 Average: 137.667 Average: 176.667
五、格式化打印
六、内建函数
6.1 数学函数
6.2 字符串函数
6.3 时间函数
七、自定义函数
7.1 定义函数
7.2 使用自定义函数
7.3 创建函数库
八、实例