比较表达式比较行,如果行里的条件为真,就执行操作。如果给表达式求值
为真则值等于1,反之等于0。
1.关系操作符
下表列出了关系操作符。 (表)!!!!!!!
关系操作符举例:
$ cat employees
Tom Jones 4423 5/12/66 543354
Mary Adams 5346 11/4/63 28765
Sally Chang 1654 7/22/54 650000
Billy Black 1683 9/23/44 336500
$ awk '$3==4423' employees
Tom Jones 4423 5/12/66 543354
$ nawk '$3 >5000{print $1}' employees
Mary
$ nawk '$2 !~/Adam/' employees
Tom Jones 4423 5/12/66 543354
Sally Chang 1654 7/22/54 650000
Billy Black 1683 9/23/44 336500
条件表达式:一个条件表达式用两个符号,问号和冒号来给表达式求值。与一个if/else语句相比更简介。
2.条件表达式
格式:
conditional expression1?expression2:expression3
它等同于{if(expression1)
expression2
else
expression3
}
条件表达式举例:
nawk '{max=($1>$2)?$1:$2;print max}' employees
解释:如果第一个域大于第二个域,就把第一个域的内容赋给max,反之把第二个域的内容赋给max,然后打印max
3.计算
可以在模式里执行计算。awk以浮点方式执行所有的算术运算 (表)
4.复合模式
复合模式 (compound patterns) 是把模式和逻辑操作符相结合的表达式,给一个表达式从左到右求值。
(表)
复合模式举例:
$ nawk '$3>4000 && $3<=6000' employees
Tom Jones 4423 5/12/66 543354
Mary Adams 5346 11/4/63 28765
$ nawk '!($3>4000 && $3<=6000)' employees
Sally Chang 1654 7/22/54 650000
Billy Black 1683 9/23/44 336500
5.范围模式
范围模式从一个模式的第一次出现匹配到第二个模式的第一次出现,然后从第一个模式的第二次出现匹配到第二个模式的第二次出现等等。如果第一个模式被匹配,而第二个模式没有找到,则awk将显示直到末尾的所有行。
例子:
$ cat datafile
northwest NW Joel Craig 3.0 .98 3 4
western WE Sharon Kelly 5.3 .97 5 23
southwest SW Chris Foster 2.7 .8 2 18
southern SO May Chin 5.1 .95 4 15
southeast SE Derek Johnson 4.0 .7 4 17
eastern EA Susan Beal 4.4 .84 5 20
northeast NE TJ Nichols 5.1 .94 3 13
north NO Val Shultz 4.5 .89 5 9
central CT Sheri Watson 5.7 .94 5 13
$ nawk '/^north/,/^west/' datafile
northwest NW Joel Craig 3.0 .98 3 4
western WE Sharon Kelly 5.3 .97 5 23
northeast NE TJ Nichols 5.1 .94 3 13
north NO Val Shultz 4.5 .89 5 9
central CT Sheri Watson 5.7 .94 5 13
6.一个数据有效性检查程序
本例子使用passwd文件,内容如下:
tooth:pwHfudo.eC9sM:476:40:Contract Admin.:/home/rickenbacker/tooth:/bin/csh
lisam:9JY7OuS2f3lHY:4467:40:Lisa M. Spencer:/home/fortune1/lisam:/bin/csh
goode:v7Ww.nWJCeSIQ:32555:60:Goodwill Guest User:/usr/goodwill:/bin/csh
bonzo:eTZbu6M2jM7VA:5101:911: SSTOOL Log account :/home/sun4/bonzo:/bin/csh
info:mKZsrioPtW9hA:611:41:Terri Stern:/home/chewie/info:/bin/csh
cnc:IN1IVqVj1bVv2:10209:41:Charles Carnell:/home/christine/cnc:/bin/csh
bee:*:347:40:Contract Temp.:/home/chanel5/bee:/bin/csh
friedman:oyuIiKoFTV0TE:3561:50:Jay Friedman:/home/ibanez/friedman:/bin/csh
chambers:Rw7R1k77yUY4.:592:40:Carol Chambers:/usr/callisto2/chambers:/bin/csh
gregc:nkLulOg:7777:30:Greg Champlin FE Chicago
ramona:gbDQLdDBeRc46:16660:68:RamonaLeininge MWA CustomerService Rep:/home/forsh:/bin/csh
要求程序能够显示域个数不等于 7 的行、第一个域不包含数字字母的行、第二个域等于星号的行。程序写在ex_6.8.nawk文件中,内容如下:
# nawk script (covered later in the chapter)
# To demonstrate example 6.8 using this script, run
# % nawk -f ex_6.8.nawk passwd
BEGIN {FS = ":"}
NF != 7 { printf("line %d, does not have 7 fields: %s\n",NR,$0)}
$1 !~ /[A-Za-z0-9]/{printf("line %d, nonalphanumeric user id: %s\n"NR,$0)}
$2 == "*" {printf("line %d, no password: %s\n",NR,$0)}
下面是调用方法和执行结果:
$ awk -f ex_6.8.nawk passwd
line 7, no password: bee:*:347:40:Contract Temp.:/home/chanel5/bee:/bin/csh
line 10, does not have 7 fields: gregc:nkLulOg:7777:30:Greg Champlin FE Chicago
7.练习题参考
现在有lab4.data文件,内容如下:
Mike Harrington:(510) 548-1278:250:100:175
Christian Dobbins:(408) 538-2358:155:90:201
Susan Dalsass:(206) 654-6279:250:60:50
Archie McNichol:(206) 548-1348:250:100:175
Jody Savage:(206) 548-1278:15:188:150
Guy Quigley:(916) 343-6410:250:100:175
Dan Savage:(406) 298-7744:450:300:275
Nancy McNeil:(206) 548-1278:250:80:75
John Goldenrod:(916) 348-4278:250:100:175
Chet Main:(510) 548-5258:50:95:135
Tom Savage:(408) 926-3456:250:168:200
Elizabeth Stachelin:(916) 440-1763:175:75:300
1) 打印那些第一个月捐款超过100的人的姓名
$ awk -F: '$3>100 {print $1}' lab4.data
2) 打印那些第一个月捐款少于$60的人的姓名和电话号码
$ awk -F: '$3<60{print $1,$2}' lab4.data
3) 打印那些第三个月捐款在90到150之间的人
$ awk -F: '$5>=90 && $5<=150 {print $0}' lab4.data
4) 打印那些三个月捐款在800以上的人
$ awk -F: '$3+$4+$5>800 {print $0}' lab4.data
5) 打印那些平均每月捐款大于$150的人名和点话号码
$ nawk -F'[ :\t]' '($5+$6+$7)/3>150{print $1,$3,$4}' lab4.data
6) 打印那些区号不是916的人名
$ nawk -F'[ :\t]' '$3 !~/916/{print $1}' lab4.data
7) 打印每条记录,记录号在前面
$ awk '{print NR,$0}' lab4.data
8) 打印每个人的名字和捐款总额
$ nawk -F'[ :\t]' 'sum=($5+$6+$7) {print $1,sum}' lab4.data
9) 把Elizabeth的第二次捐款加上$10
$ nawk -F'[ :\t]' 'juankuan=($1 ~/Elizabeth/)?$6+10:$6{print $1,juankuan}' lab4.data
10) 把Nancy McNeil的名字改成Louise McInnes
$ nawk 'name=($1 ~/Nancy/)?"Louise McInnes":$1{print name}' lab4.data