awk连载7: awk while循环
语法: while(判断){操作}
如果判断成立,则执行{}里的操作,完了之后再回头到判断()里语句是否成立,如果不成立则跳出循环,如果还成立,则继续执行()里的操作。
先看aa.txt的内容:
[root@vms63 ~]# cat aa.txt
aaa 1 root 11111
bbb 2 ro2t 222 ddd aaa
ccc 3 xxxx r22t dddd
ddd 4 yyy root 222
eee 5 aaa zzz
[root@vms63 ~]#
如果在while的()里使用变量的话,则变量需要预先定义出来,比如想打印每行的前两个字段:
awk '{i=1;while(i <=2){print $1}}' aa.txt
这里while里用了i,所以在while之前需要先把i定义出来i=1。然后开始while循环,如果i的值小于2,则执行print $1。
这里会存在一个问题就是,i的值一开始为1,它是小于2的,条件成立然后执行print $1,打印完成之后,再回头到()里判断条件是否是成立的,因为$i的值并没有发生变化仍然是1, 所以这是一个死循环,会一直循环下去。
为了解决这个问题,希望每次循环i的值都要有所改变,此时可以使用递增的用法如下:
awk '{i=1;while(i<=2){print $i ; i++}}' aa.txt
解释
先定义i的值为1,然后开始判断i的值是否小于2,如果满足条件则打印$1,然后i自增1变成2,再次返回()里继续判断是否满足小于2,依次类推打印出来$1和$2。因为print打印出来的结果是自带换行符的,所以此句打印出来的结果如下:
注意:这里每次循环新一行的时候,i都会初始化为1。
可以把print换成printf,这样打印的结果就没有换行符了:
可以设置,打印完没一行之后,回车,可以这样
awk '{i=1;while(i<=2){printf $i" " ; i++} ; print ""}' aa.txt
得到的结果为
其实上面的结果利用awk '{print $1,$2}' aa.txt就可以实现,但是可以让我们理解while的用法。
练习1:
打印aa.txt的前两行的内容:
练习2
找到dd.txt里 每行中符合/xy/xNNN.pl (此处N为数字)格式的字符串:
[root@vms63 ~]# awk '{
> i=1;while(i<=NF){
> if($i ~ /\/xy\/x[0-9]+\.pl/){print $i}; i++
> }}' dd.txt
/xy/x111.pl
/xy/x222.pl
/xy/x23.pl
[root@vms63 ~]#