广州-戴同学 2012/6/29 19:20:29

4
seq 100 |awk 'i=!i'
awk 那段是怎么理解?

首先我们要了解一下awk对于未定义的变量处理方法:

对于数值运算,未定义变量的话awk会赋予变量初值为0

对于字符运算,未定义变量的话awk会赋予变量初值为空字符串

了解了这两条我们再看awk 'i=!i'这条命令是什么含义,awk是对文本文件一行一行处理的,seq 100命令执行后是如下形式:

1

2

3

……

100

首相它读取第一行数据,也就是1,然后进行模式匹配,i是一个未定义的变量,上面我们提到了对于数值运算,未定义变量的话初值会为0,这时i的值即为0,也就是i=!0,那么!是什么呢?!就是取反的意思,等号右边其实就是个布尔值,0为假,1为真,这里是!0,那么它就为非假,也就是为真,真的值为1,因此i=!0(1)也就相当于i=1,到此i的值为1.

 

i的值为1后有什么作用呢?

i=1说明值为真,awk会认定模式为真,这时匹配是成功的,会把第一行输出到屏幕,可能有的人会问了这里只有i=!i,没有print,它怎么输出的?awk的格式为 模式{ 动作},如果只有模式没有动作,那么匹配成功后默认的会输出整条记录,也就是说这条命令完整的写法为:

seq 1 100 | awk 'i=!i{print $0}'

为什么第二行没有输出呢?

前面进行第一行模式匹配的时候i的值已经由0变为了1,在进行第二行操作的时候,i=!i变成了i=!1,这样i的值就又变成了0(假),所以第二行没有输出,到了处理第三行的时候,i=!i变成了i=!0,所以会输出第三行,以此类推……这样我们就可以输出奇数行而删除偶数行了。

那么如何输出偶数行呢?

我们可以加一个if判断一下,如果i的值为真我们就输出奇数行,如果为假就输出偶数行

[root@LNMP ~]# seq 1 10 | awk '{i=!i;if(i) print $0}'

1
3
5
7
9
[root@LNMP ~]# seq 1 10 | awk '{i=!i;if(!i) print $0}'
2
4
6
8
10

看到这儿又有朋友可能会问了,为什么现在把i=!i放到动作里了呢?

我们看这两条命令:

[root@LNMP ~]# seq 1 10 | awk 'i=!i{print !i}'

0
0
0
0
0
[root@LNMP ~]# seq 1 10 | awk 'i=!i{print i}'
1
1
1
1
1

如果把i=!i放到模式里边它会进行匹配,把匹配的结果传递给动作,那个时候已经把不匹配的舍去了,所以我们无法用if来判断i的值。

 

本人对awk理解也不是很深刻,难免有误,如果有不对的地方还请各种兄弟多多指教!