+ -
当前位置:首页 → 问答吧 → awk之选择性打印

awk之选择性打印

时间:2011-02-17

来源:互联网

本帖最后由 yinyuemi 于 2011-02-17 11:10 编辑

最近的帖子中有不少是关于选择性打印的,自认为用awk来处理这样的文本是有很大的优势,而且很容易理解。
在处理这类问题时,可以通过设置一些变量作为打印标签,达到选择的目的。
另,还可以利用awk自身的函数如NF,RS,RT,FS等,有时会达到意想不到的效果。

下面是就自己的一些理解做了下总结,如有不对之处,望不吝指正!

1. 按照某个pattern取其前后几行数据:
  1. cat file
  2. aaa
  3. bbb
  4. ccc
  5. ddd
  6. eee
  7. fff
  8. ggg
  9. hhh
复制代码
1.1 pattern等于ddd时,取其前1行:
  1. awk '!/ddd/{m=$0}/ddd/{print m}' file
  2. ccc
复制代码
如果是取其前n行,需要借助下数组,以前3行为例
  1. $ awk '{a[NR]=$0}/ddd/{p=NR}END{for(i=p-3;i<p;i++) printf a[i] RS}' file
  2. aaa
  3. bbb
  4. ccc
复制代码
1.2 pattern等于ddd时,取其后n行,这个就要简单的多,以后3行为例
  1. awk '/ddd/{p=1;x=NR}p&&NR-x<=3&&NR-x>0' file
  2. eee
  3. fff
  4. ggg
复制代码
这就可以用awk实现,grep -A /grep -B 的功能。

1.3 如果对pattern出现的次数有要求时,第二次匹配aaa时取后2行
  1. cat file

  2. aaa
  3. bbb
  4. ccc
  5. aaa
  6. 111
  7. 222
  8. aaa
  9. 333
  10. 444

  11. awk '/aaa/{m++;x=NR}m==2&&NRx<=2 && NR-x>0' file
  12. 111
  13. 222
复制代码
2. 按照某2个pattern,取其间数据
  1. cat file
  2. aaa
  3. bbb
  4. ccc
  5. ddd
  6. eee
  7. fff
  8. ggg
  9. hhh
复制代码
如,匹配取匹配bbb和fff之间的数据

2.1 包括匹配行
  1. awk '/bbb/{p=1}/fff/{print;p=0}p' file
  2. bbb
  3. ccc
  4. ddd
  5. eee
  6. fff
复制代码
2.2 不包括bbb行
  1. awk '/bbb/{p=1;next}/fff/{print;p=0}p' file
  2. ccc
  3. ddd
  4. eee
  5. fff
复制代码
2.3 不包括fff行
  1. awk '/bbb/{p=1}/fff/{p=0}p' file
  2. bbb
  3. ccc
  4. ddd
  5. eee
复制代码
2.4 不打印匹配行
  1. awk '/bbb/{p=1;next}/fff/{p=0}p' file
  2. ccc
  3. ddd
  4. eee
复制代码
3. 删除或保留含有某个pattern的数据块,看个实例吧:
  1. cat file

  2. DFDG
  3. START
  4. DSFDS
  5. DSDS
  6. XXX
  7. END
  8. AADD
  9. START
  10. SDSD  (VIO)
  11. FGFG
  12. END
  13. START
  14. DSFDS
  15. DSDS
  16. XXX
  17. END
  18. START
  19. adad (VIO)
  20. gfthgh
  21. END
复制代码
要求是保留从START 到 END 之间含有(VI0)的数据。

代码1:
  1. awk '/START/{p++}/./{a[p]=a[p]"\n"$0}END{for(i=1;i<=p;i++) if(a[i]~/\(VIO\)/) print a[i]}' file

  2. START
  3. SDSD  (VIO)
  4. FGFG
  5. END

  6. START
  7. adad (VIO)
  8. gfthgh
  9. END
复制代码
这段代码将打印标签(p)作为数据下标,把每段从START到END之间数据存入数组中,最后打印匹配(VIO)的数组值。

代码2:
  1. awk -v RS="START" '/VIO/{print RS $0}' file
  2. START
  3. SDSD  (VIO)
  4. FGFG
  5. END

  6. START
  7. adad (VIO)
  8. gfthgh
  9. END
复制代码
这段代码巧妙地利用awk的内置函数RS。


<未完>

作者: yinyuemi   发布时间: 2011-02-17

回复 yinyuemi


    学习~~

作者: 好看的附件   发布时间: 2011-02-17

热门下载

更多