广州-戴同学 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理解也不是很深刻,难免有误,如果有不对的地方还请各种兄弟多多指教!