免费注册 查看新帖 |

Chinaunix

广告
  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: unixzhong
打印 上一主题 下一主题

awk 实现 grep -A3 -B3 的效果,文本10G行 [复制链接]

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
11 [报告]
发表于 2011-03-23 18:06 |只看该作者
回复 10# unixzhong
  1. awk -f grepC.awk urfile
复制代码
grepC.awk
  1. {
  2.     if (/B/) {
  3.         if (!f) {
  4.             if (p) {
  5.                 if ( mN && NR - lpN > 3) print "--";
  6.                 print p;
  7.                 p = "";
  8.             }
  9.             f = !f;
  10.         }
  11.         mN = NR;
  12.         print;
  13.         lpN = NR;
  14.     } else if (f) {
  15.         if (NR-mN > 3) {
  16.             f = !f;
  17.             if (gsub(/\n/,"\n",p) > 1) sub(/[^\n]*\n/,"",p);
  18.             p = p?p"\n"$0:$0;
  19.         } else {
  20.             print;
  21.             lpN = NR;
  22.         }
  23.     } else {
  24.         if (gsub(/\n/,"\n",p) > 1) sub(/[^\n]*\n/,"",p);
  25.         p = p?p"\n"$0:$0;
  26.     }
  27. }
复制代码

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
12 [报告]
发表于 2011-03-24 01:53 |只看该作者
本帖最后由 yinyuemi 于 2011-03-26 01:23 编辑
回复  blackold

黑哥:

我的代码已经可以处理 重叠的情况了,就是想看看有没有其他 思路,当然我希望 ...
unixzhong 发表于 2011-03-23 15:39
  1. awk '{a[++p]=$0}

  2. /B/{p>f+3;print "-----"

  3.         f=p;

  4.         for(i=p-3;i<=p;i++)

  5.                 if((!(i in b))&&a[i]){print a[i];b[i]}

  6.     }

  7. NR==f+3&&f{

  8.         for(k=NR-2;k<=NR;k++)

  9.                 if((!(k in b))&&a[k]){print a[k];b[k]}

  10.              }'
复制代码
这个应该会快点

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
13 [报告]
发表于 2011-03-24 10:07 |只看该作者
刚才做了测试,grep快很多,有时间可以看看grep的源码。

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
14 [报告]
发表于 2011-03-24 10:14 |只看该作者
刚才做了测试,grep快很多,有时间可以看看grep的源码。
blackold 发表于 2011-03-24 10:07



    恩,我也测试了,
seq 1000000 |awk 'END{print}'

seq 1000000 | grep -A3 -B3 -w 5000
用的时间几乎一样

论坛徽章:
0
15 [报告]
发表于 2011-03-25 18:19 |只看该作者
本帖最后由 unixzhong 于 2011-03-25 18:48 编辑

回复 11# blackold


    快速扫描了下黑哥代码,发现的确没有用 a[NR]=$0
心里肯定了, 有不那么耗费内存的方式。
(  我一楼代码里面  那种方式吃太多内存 ----------------数组保存所有行)

再看了下 黑哥代码,自己功力太浅,看的有点头晕,因为没有 了解 黑哥的思路。

就暂时不敢回贴了。

后来就放一边了, 看其他awk代码去了,嘿嘿,从 tail -n 2 的awk实现例子里,得到了一点启发。

于是 有了下面的  我的新实现了 (只需要一个 小 数组 临时 保存 当前行 和 它的前3行即可  )

经过验证,才敢贴上来

man find | awk -f mygrep_atime_nodebug.awk  > mygrep_output

man find |  grep -A3 -B3  atime  > grep_output

diff mygrep_output  grep_output 没输出 :)
  1. BEGIN { Last_Range_End=0; Range_End=0;  for(i=0;i<=3;i++)keep[i]="" }


  2. {for(j=3;j>0;j--)keep[j]=keep[j-1];  keep[0]=$0}
  3. NR<=Range_End { print $0 }



  4. /atime/{ Last_Range_End=Range_End; Range_End= NR + 3;

  5.                 if (  Last_Range_End < NR )
  6.                          {
  7.                         non_intersect_lines=(4 - (NR - Last_Range_End) )>0? (NR - Last_Range_End) :4 ;
  8.                         if(non_intersect_lines==4) print "--" ;  
  9.                         for(i=non_intersect_lines-1;i>=0;i--) print keep[i]
  10.                         }
  11.           }
复制代码
回家

论坛徽章:
0
16 [报告]
发表于 2011-03-25 18:27 |只看该作者
回复 14# yinyuemi


    谢谢  yinyuemi  一直以来的 热心探讨

     第一次知道 有 seq这个命令,

     能 就 如何 测量  脚本效率, 简单地 说说吗? 我还从来没 这样的经历, 多谢了。

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
17 [报告]
发表于 2011-03-26 01:28 |只看该作者
本帖最后由 yinyuemi 于 2011-03-26 12:18 编辑

回复 16# unixzhong


  这个.... , 还是高手解答吧, 时间应该算个很直观的标准!

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
18 [报告]
发表于 2011-03-29 12:05 |只看该作者
回复 15# unixzhong


    你用经典的数据来测试, 就发现和grep的输出有差别了。

论坛徽章:
0
19 [报告]
发表于 2011-03-31 17:51 |只看该作者
回复 5# yinyuemi

经!!!

论坛徽章:
0
20 [报告]
发表于 2011-04-01 14:39 |只看该作者
既然是Awk就可以用Awk way, 扔给awk自己处理不知道会不会快一些:

  1. awk 'BEGIN{FS="\n"; RS=EOF} {代码}'
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP