Chinaunix

标题: awk中地址表示的小技巧 [打印本页]

作者: woodie    时间: 2006-01-21 19:09
标题: awk中地址表示的小技巧
sed中表示地址或地址范围大家都很熟悉,今天贴几个awk中地址表示的小技巧:
  1. 第一行:        NR==1 或 !i++
  2. 第n行:        NR==n
  3. 最后一行:       0 或 "" 或 1==0 或 1>2 ,总之任一个假值就可以
  4. 匹配正则表达式RE的行: /RE/
复制代码


举例:
  1. $ seq 10 |awk  '!i++,/3/; NR==6, 0'
  2. 1
  3. 2
  4. 3
  5. 6
  6. 7
  7. 8
  8. 9
  9. 10
复制代码


等价的sed命令:
  1. sed -ne '1,/3/p;6,$p'
复制代码

[ 本帖最后由 woodie 于 2006-1-21 19:11 编辑 ]
作者: 寂寞烈火    时间: 2006-01-21 20:18
学习
作者: 大蚂蚁    时间: 2006-01-21 20:45
!i++

这个怎么解?
作者: ruifox    时间: 2006-01-21 21:22
最后一行的表示方法不行啊!
!i++也莫名其妙
作者: 寂寞烈火    时间: 2006-01-22 01:31
也许写成这样,更容易理解
awk 'NR==1,/3/;NR>=6'
作者: ruifox    时间: 2006-01-22 08:42
不行也不懂!请楼上解释一下!
作者: woodie    时间: 2006-01-22 11:32
原帖由 大蚂蚁 于 2006-1-21 20:45 发表
!i++

这个怎么解?


这个条件只在第一行时为真一次,然后永远为假,与NR==1等价。
i的初值为0,0在awk中是假值的一种,取反即为真。当i非0时,i为真,取反即为假。
这个有点变态了,大家忘掉它也罢。^_^
作者: woodie    时间: 2006-01-22 11:36
原帖由 ruifox 于 2006-1-21 21:22 发表
最后一行的表示方法不行啊!
!i++也莫名其妙

你的awk可能版本较老,请换个awk试试。
0是简单的假值表示法。也许空串""在你的环境下能够工作?
作者: woodie    时间: 2006-01-22 11:42
原帖由 寂寞烈火 于 2006-1-22 01:31 发表
也许写成这样,更容易理解
awk 'NR==1,/3/;NR>=6'

火兄的这个不错!赞一个。更加简洁,但适用性稍差。
考虑以下这个情况,打印匹配行之后的所有行:
awk '/RE/,0'
此时NR>=linenumber的语法就不行了。
作者: 寂寞烈火    时间: 2006-01-22 11:50
原帖由 woodie 于 2006-1-22 11:42 发表

火兄的这个不错!赞一个。更加简洁,但适用性稍差。
考虑以下这个情况,打印匹配行之后的所有行:
awk '/RE/,0'
此时NR>=linenumber的语法就不行了。

受教
作者: __lxmxn__    时间: 2007-05-08 13:14
楼主强人啊,顶一个。

另外,这个“sed -ne '1,/3/p;6,$p'”参数 -ne 和 p 分别是什么意思啊?小弟初学sed,请大侠不吝赐教。
作者: woodie    时间: 2007-05-08 17:13
man sed。
-n选项表示不执行打印模式空间的缺省动作
p指令表示强制打印模式空间的内容。
-e表示后面的参数是sed脚本,某些情况下可以省略。
作者: vkill    时间: 2007-05-08 18:58
!i++ 用的真bt 哈哈
作者: vkill    时间: 2007-05-08 19:02
sed -ne '1,/3/p;6,$p'

这句写的不怎么对吧?
这样的意思是显示 第一行到第一次出现含有3的行  和   第6行到尾行

貌似是下面这样吧!
sed -ne '1,3p;6,$p'
作者: __lxmxn__    时间: 2007-05-09 00:56
应该是 sed -ne '1,/3/p;/6/,$p' 吧?
从第一行开始到第一次出现3的行,从第一次出现6的行,到结尾。
作者: 灿烂小猪    时间: 2008-06-23 10:05
真长知识了,非常感谢楼主。
作者: blackold    时间: 2008-06-23 13:32
标题: 回复 #1 woodie 的帖子
Doing Great!

说清楚这一点可能会更好:
最后一行:       0 或 "" 或 1==0 或 1>2 ,总之任一个假值就可以

并不是说"0 或 "" 或 1==0 或 1>2 ,总之任一个假值..."匹配最后一行,相反,任何最后一行都不会匹配0 "" 1>2这样的假值。只是range pattern(pattern1,pattern2)中的pattern2可以使用一个假值来使该范围包括最后一行,或者说该范围包括满足pattern1的行和该行之后的所有行。

不知道上面说得对不对,敬请斧正!

[ 本帖最后由 blackold 于 2008-6-23 13:55 编辑 ]
作者: apzc2529    时间: 2010-07-13 13:23
强贴!前来膜拜!
作者: howge    时间: 2010-07-13 13:26
回复 18# apzc2529

你挖坟啊~  学习了
作者: ywlscpl    时间: 2010-07-13 13:28
学习了
range pattern的末行表示
作者: hujysh    时间: 2010-07-13 13:43
黑老显然是对的
作者: iori809    时间: 2010-07-13 13:49
我觉得应该是这样的~你给它一个没有的值,它会一直去寻找,那么找到最后还没有,就停止了
作者: wild_li    时间: 2010-07-13 14:29
!i++确实很难理解...
作者: 1984qht    时间: 2010-07-13 14:45
{:3_189:} 学习了
作者: jerry017cn    时间: 2010-07-13 15:04
帖子够老的。。。。。

作者: where27    时间: 2010-07-13 15:24
同意梦呆呆,膜拜黑哥
作者: hujysh    时间: 2010-07-13 15:42
awk '0{print}' urfile 打印不了任何一行

awk '{a=$0}END{print a}' urfile 可以打印最后一行,但是太土

打印最后一行 有什么好办法啊?
作者: hujysh    时间: 2010-07-13 15:43
限awk啊  别sed
作者: where27    时间: 2010-07-13 15:45
回复 28# hujysh


    awk 'END{print}' file
作者: hujysh    时间: 2010-07-13 16:09
回复 29# where27


   

$ awk 'END{print}' a        

$ awk \'END{print}\' a
syntax error The source line is 1.
The error context is
                 >>> ' <<<
awk: Quitting
The source line is 1.
$ cat a
line 1
line last
$
作者: where27    时间: 2010-07-13 16:14
回复 30# hujysh
  1. # more file
  2. 1
  3. 2
  4. 3
  5. # awk 'END{print}' file
  6. 3
  7. # awk --version
  8. GNU Awk 3.1.5
复制代码
估计是awk版本原因,不知道你的什么版本
作者: hujysh    时间: 2010-07-13 16:22
回复 31# where27


   
我的是HP-UX下的ksh

我不知道怎么看版本
作者: ywlscpl    时间: 2010-07-13 16:32
本帖最后由 ywlscpl 于 2010-07-13 16:35 编辑

another way:

[root@Mylinux tmp]# seq 5 >file                  
[root@Mylinux tmp]# awk '{while (getline);}2' file
5
作者: justlooks    时间: 2010-07-13 16:36
0可不能单独用表示最后一行,只能表示未匹配,那么前面指定的数开始就一直会到最后一行
作者: hujysh    时间: 2010-07-13 16:38
回复 34# justlooks


   

理解!
谢谢!
作者: apzc2529    时间: 2010-07-18 20:08
回复 19# howge


   

哈哈
作者: expert1    时间: 2010-07-19 09:11
理解谢啦




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2