目录
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》,大家有兴趣可以买一本,也可以关注我,我更新完它。
曾经,我花费大半月将它们跑完,现在啥都忘了,还是要常用。
只为学习交流,不为获利,侵权联系立删。