windows ubuntu sed,awk,grep篇:11.awk 分支和循环

Awk 支持条件判断,控制程序流程。 Awk 的大部分条件判断语句很像 C 语言的语法。
Awk 支持下面三种 if 语句 .
单个 if 语句
If-else 语句
多级 If-elseif 语句

69. if 结构

单个 if 语句检测条件,如果条件为真,执行相关的语句。
单条语句
语法 :
if(conditional-expression )
action
 if 是关键字
conditional-expression 是要检测的条件表达式
action 是要执行的语句
多条语句
如果要执行多条语句,需要把他们放在 { } 中,每个语句之间必须用分号或换行符分开 , 如下
所示 .
语法 :
if (conditional-expression)
{
action1;
action2;
}
如果条件为真, { } 中的语句会依次执行。当所有语句执行完后, awk 会继续执行后面的语句。
打印数量小于等于 5 的所有商品:
$ awk -F ',' '{ if ($5 <= 5) print "Only",$5,"qty of",$2 "is available" }' items.txt
Only 2 qty of Refrigeratoris available
Only 5 qty of Laser Printeris available使用多个条件,可以打印价钱在 500 100,并且总数不超过 5 的商品
$ awk -F ',' '{ if (($4 >= 500 && $4<= 1000) && ($5 <= 5)) print "Only",$5,"qty of",$2,"is
available" }' items.txt
Only 2 qty of Refrigerator is available

70. if else 结构

if else 结构中,还可以指定判断条件为 false 时要执行的语句。下面的语法中,如果条件
true ,那么执行 action1, 如果条件为 false, 则执行 action2
语法 :
if (conditional-expression)
action1
else
action2
此外, awk 还有个条件操作符 ( ? : ) ,和 C 语言的三元操作符等价。
if-else 结构相同,如果 codintional-expresion true, 执行 action1, 否则执行 action2
三元操作符 :
codintional-expression ? action1 : action2 ;
如果商品数量不大于 5,打印”Buy More”,否则打印商品数量:
$ cat if-else.awk
BEGIN {
FS=",";
}
{
if( $5 <= 5)
print "Buy More: Order",$2,"immediately!"
else
print "Shell More: Give discount on",$2,"immediately!"
}
$ awk -f if-else.awk items.txt
Shell More: Give discount on HD Camcorder immediately!
Buy More: Order Refrigerator immediately!
Shell More: Give discount on MP3 Player immediately!
Shell More: Give discount on Tennis Racket immediately!
Buy More: Order Laser Printer immediately!
下面的例子,使用三元操作符,把 items.txt 文件中的每两行都以逗号分隔合并起来。
$ awk 'ORS=NR%2?",":"\n"' items.txt
101,HD Camcorder,Video,210,10,102,Refrigerator,appliance,850,2
103,MP3 Player,Audio,270,15,104,Tennis Racket,Sports,190,20
( 复杂的就是 awk '{if(NR%2==0) ORS="\n"; else ORS=",";print}' items.txt)

71. while 循环

Awk 循环用例执行一系列需要重复执行的动作,只要循环条件为 true ,就一直保持循环。和
C 语言类似, awk 支持多种循环结构。
首先是 while 循环结构 .
语法 :
while (codition)
Actions
while awk 的关键字
condition 是条件表达式
actions 是循环体,如果有多条语句,必须放在 { }
while 首先检查 condtion, 如果是 true ,执行 actions, 执行完后,再次检查 condition, 如果是 true
再次执行 actions, 直到 condition false 时,退出循环。
注意,如果第一次执行前 condition 返回 false ,那么所有 actions 都不会被执行。
下面的例子中,BEGIN 区域中的语句会先于其他 awk 语句执行。While 循环将 50 ’x’追加到
变量 string 中。每次循环都检查变量 count,如果其小于 50,则执行追加操作。因此循环体会
执行 50 次,之后,变量 string 的值被打印出来。
$ awk 'BEGIN { while(count++<50) string=string "x"; print string}'
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
下面的例子计算 items-sold.txt 文件中,每件商品出售的总数。
对于每条记录,需要把从第 2 至第 7 个字段累加起来 ( 第一个字段是编号,因此不用累加 )
所以,当循环条件从第 2 个字段 ( 因为 while 之前设置了 i=2), 开始,检查是否到达最后一个字
(i<=NF) NF 代表每条记录的字段数。
$ cat while.awk
{
i=2; total=0;
while (i <= NF ){
total = total + $i;
i++;
}
print "Item",$1,":",total,"quantities sold";
}$ awk -f while.awk items-sold.txt
Item 101 : 47 quantities sold
Item 102 : 10 quantities sold
Item 103 : 65 quantities sold
Item 104 : 20 quantities sold
Item 105 : 42 quantities sold

72. do-while 循环

While 循环是一种进入控制判断的循环结构,因为在进入循环体前执行判断。而 do-while
环是一种退出控制循环,在退出循环前执行判断。 do-while 循环至少会执行一次,如果条
件为 true ,它将一直执行下去。
语法 :
do
action
while(condition)
下面的例子中, print 语句仅会执行一次,因为我们已经确认判断条件为 false 。如果这是一
while 结构,在相同的初始化条件下, print 一次都不会执行。
$ awk 'BEGIN {
> count=1;
> do
> print "This gets printed at least once";
> while(count!=1)
> }'
This gets printed at least once
下面打印 items-sold.txt 文件中,每种商品的总销售量,输出结果和之前的 while.awk 脚本相
同,不同的是,这次试用 do-while 结构来实现。
$ cat dowhile.awk
{
i=2;
total=0;
do {
total = total + $i;
i++;
}
while(i<=NF)
print "Item",$1,":",total,"quantities sold";
}
$ awk -f dowhile.awk items-sold.txt
Item 101 : 47 quantities sold
Item 102 : 10 quantities sold
Item 103 : 65 quantities sold
Item 104 : 20 quantities sold
Item 105 : 42 quantities sold

73. for 循环

Awk for 循环和 while 循环一样实用,但语法更简洁易用。
语法:
for(initialization;condition;increment/decrement)
for 循环一开始就执行 initialization ,然后检查 condition, 如果 condition true ,执行 actions,
然后执行 increment decrement. 如果 condition true ,就会一直重复执行 actions
increment/decrement
下面例子打印文件总字段数总和。I 的初始值为 1,如果 i 小于等于字段数,则当前字段会被
追加到总数中,每次循环 i 的值会增加 1.
$ echo "1 2 3 4" | awk '{ for (i=1;i<=NF;i++) total = total + $i } END { print total }'
10
下面的例子,使用 for 循环把文件中的字段反序打印出来。注意这次在 for 中使用 decrement
而不是 increment
提示:每读入一行数据后, awk 会把 NF 的值设置为当前记录的总字段数。
该例用相反的顺序,从最后一个自动开始到第一个字段,逐个输出每个字段。然后输出换行。
反转示例 :
$ cat forreverse.awk
BEGIN {
ORS="";
}
{
for (i=NF;i>0;i--)
print $i," "
print "\n";
}
$ awk -f forreverse.awk items-sold.txt
12 10 8 5 10 2 101
2 0 3 4 1 0 102 13 5 20 11 6 10 103
5 6 0 4 3 2 104
6 12 7 5 2 10 105
之前我们用 while do-while 循环,输出了 items-sold.txt 中每种商品的销售量,现在我们推
出该程序的 for 循环版本。
$ cat for.awk
{
total=0;
for(i=2;i<=NF;i++)
total = total + $i
print "Item ",$1," : ",total," quantities sold"
}
$ awk -f for.awk items-sold.txt
Item 101 : 47 quantities sold
Item 102 : 10 quantities sold
Item 103 : 65 quantities sold
Item 104 : 20 quantities sold
Item 105 : 42 quantities sold

74. break 语句

Break 语句用来跳出它所在的最内层的循环 (while,do-while, for 循环 ) 。请注意, break 语句
只有在循环中才能使用。
打印某个月销售量为 0 的任何商品,即从第 2 至第 7 个字段中出现 0 的记录。
$ cat break.awk
{
i=2;total=0;
while(i++<=NF)
{
if($i == 0)
{
print "Item",$0,"had a month without item sold"
break
}
}
}
$ awk -f break.awk items-sold.txt
Item 102 0 1 4 3 0 2 had a month without item sold
Item 104 2 3 4 0 6 5 had a month without item sold 如果执行下面的命令,要按 Ctrl+c 才能停止。
$ awk ‘BEGIN{while(1) print “forever”}’
这条语句一直打印字符串 ”forever”, 因为条件永远不为 false 。尽管死循环会用于操作系统和
进程控制,但通常不是什么好事。
下面我们修改这个死循环,让它执行 10 次后退出
$ awk 'BEGIN{
> x=1;
> while(1)
> {
> print "Iteration"
> if( x==10)
> break;
> x++
> }}'
其输出结果如下 :
Iteration
Iteration
Iteration
Iteration
Iteration
Iteration
Iteration
Iteration
Iteration
Iteration

75. continue 语句

Continue 语句跳过后面剩余的循环部分,立即进入下次循环。请注意, continue 只能用在循
环当中。
下面打印 items-sold.txt 文件中所有商品的总销售量。其输出结果和 while.awk dowhile.awk
以及 for.awk 一样,但是这里的 while 循环中使用 contine ,使循环从 1 而不是从 2 开始。
$cat continue.awk
{
i=1;total=0;
while(i++<=NF)
{
if(i==1)
continue
total = total + $i }
print "Item",$1,":",total,"quantities sold"
}
$ awk -f continue.awk items-sold.txt
Item 101 : 47 quantities sold
Item 102 : 10 quantities sold
Item 103 : 65 quantities sold
Item 104 : 20 quantities sold
Item 105 : 42 quantities sold
下面的脚本在每次循环时都打印 x 的值,除了第 5 次循环,因为 continue 导致跳打印语句。
$ awk 'BEGIN{
> x=1;
> while(x<=10)
> {
> if(x==5)
> {
> x++
> continue
> }
> print "Value of x:",x;x++;
> }
> }'
输出结果如下 :
Value of x: 1
Value of x: 2
Value of x: 3
Value of x: 4
Value of x: 6
Value of x: 7
Value of x: 8
Value of x: 9
Value of x: 10

76. exit 语句

exit 命令立即停止脚本的运行,并忽略脚本中其余的命令。
exit 命令接受一个数字参数最为 awk 的退出状态码,如果不ᨀ供参数,默认的状态码是 0.
下面的脚本执行到第 5 次循环时退出,因为 print 命令位于 exit 之后,所以输出的值只到 4
为止,到第 5 次循环时就退出了。
$ awk 'BEGIN{
> x=1;
> while(x<=10)
> {
> if(x==5)
> {
> x++
> exit
> }
> print "Value of x:",x;x++;
> }
> }'
其输出结果如下 :
Value of x: 1
Value of x: 2
Value of x: 3
Value of x: 4
下面例子打印第一次出现的有个月没有卖出一件的商品的信息。和 break.awk 脚本很相似,
区别在于,遇到某月为出售的商品时,退出脚本,而不是继续执行。
$ cat exit.awk
{
i=2;total=0;
while(i++<=NF)
if($i==0) {
print "Item",$1,"had a month with no item sold"
exit
}
}
$ awk -f exit.awk items-sold.txt
Item 102 had a month with no item sold
提示: 104 号商品有的月份也没有卖出一件,但是并没有被打印,因为我们在循环中使用了
exit 命令。

资料来源于《SedandAwk101Hacks》,大家有兴趣可以买一本,也可以关注我,我更新完它。

曾经,我花费大半月将它们跑完,现在啥都忘了,还是要常用。

只为学习交流,不为获利,侵权联系立删。

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值