免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3730 | 回复: 13

[文本处理] awk取a跟b间的内容,我理解错误,求指点 [复制链接]

论坛徽章:
2
15-16赛季CBA联赛之八一
日期:2017-07-06 14:20:4715-16赛季CBA联赛之上海
日期:2017-08-21 22:14:34
发表于 2017-07-06 17:10 |显示全部楼层
本帖最后由 irockey 于 2017-07-06 20:26 编辑

如果是匹配以A开头,以B结尾的内容,同时A和B之间还包含C的这种怎么做?
比如

  1. [root@localhost ~]#cat file
  2. aaa
  3.   grge
  4.   ddd
  5. bbb

  6. aaa gege
  7. ccc
  8. bbb

  9. aaa gregeg
  10.   eee
  11. bbb
复制代码


这个中A=aaa,B=bbb,C=ccc,那么要提取出下面的……
aaa gege
ccc
bbb



awk '/aaa/{t=1}{if(t)s=length(s)?s"\n"$0:$0}/bbb/{t=0;if(s~/ccc/)print s;s=""}' file

第一行
pattern1{action1}
        匹配包含aaa的行,满足条件令t=1,当t=1时,if条件为真,执行s=length(s)?s"\n"$0:$0

        这里s=length(s)?s"\n"$0:$0又是一个判断,s=length(s)为真,执行s"\n"$0,否则执行$0
                s是自定义变量,当s未定义时,s="",
               
                man awk中length函数的解释

                length()             Return the length of the string s, or the length of $0 if s is not supplied.
               
                length(s)=length($0),即length(aaa)=3,表达式为真,此时执行第1个表达式  s"\n"$0
               
  1. [root@localhost ~]#echo "aaa" | awk '{s=length(s)?s"\n"$0:$0}END{print s}'
  2. aaa
  3. [root@localhost ~]#echo "aaa" | awk '{s=length(s)}END{print s}'
  4. 0
复制代码



               这里是不是要把length(s)?s"\n"$0:$0看做一个整体,这是优先级原因么?感觉我上面的理解是错误的
        
pattern2{action2}
匹配包含bbb的行
        s为从aaa开始的字符串
        判断字符串中是否包含ccc(正则表达式)
                满足条件,则打印s
                不满足将s变量置空

第二行
        不匹配aaa,
        
        我不知道我哪一步开始理解错了,请大神指点下

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
发表于 2017-07-06 17:28 |显示全部楼层
添加一个计数器

论坛徽章:
54
2015亚冠之德黑兰石油
日期:2015-07-07 13:00:1615-16赛季CBA联赛之深圳
日期:2016-03-31 09:03:5415-16赛季CBA联赛之辽宁
日期:2016-05-09 20:38:15程序设计版块每日发帖之星
日期:2016-05-12 06:20:0015-16赛季CBA联赛之四川
日期:2016-05-13 15:19:4715-16赛季CBA联赛之福建
日期:2016-05-15 20:24:34每日论坛发贴之星
日期:2016-05-16 06:20:0015-16赛季CBA联赛之吉林
日期:2016-05-26 11:49:4715-16赛季CBA联赛之广东
日期:2016-05-26 13:49:18极客徽章
日期:2016-12-07 14:05:2315-16赛季CBA联赛之广夏
日期:2016-12-20 17:33:532017金鸡报晓
日期:2017-01-10 15:19:56
发表于 2017-07-06 17:37 |显示全部楼层
  1. awk '/^aaa/{t=1};/^bbb/{if(s~/ccc/){print s"\n"$0};s=a;t=0}t{s=s?s"\n"$0:$0}' a
复制代码


  1. awk '/^aaa/{s=$0;next};/^bbb/{if(s~/ccc/)print s"\n"$0;next}{s=s"\n"$0}' a
复制代码

论坛徽章:
307
程序设计版块每周发帖之星
日期:2016-04-08 00:41:33操作系统版块每日发帖之星
日期:2015-09-02 06:20:00每日论坛发贴之星
日期:2015-09-02 06:20:00程序设计版块每日发帖之星
日期:2015-09-04 06:20:00每日论坛发贴之星
日期:2015-09-04 06:20:00每周论坛发贴之星
日期:2015-09-06 22:22:00程序设计版块每日发帖之星
日期:2015-09-09 06:20:00程序设计版块每日发帖之星
日期:2015-09-19 06:20:00程序设计版块每日发帖之星
日期:2015-09-20 06:20:00每日论坛发贴之星
日期:2015-09-20 06:20:00程序设计版块每日发帖之星
日期:2015-09-22 06:20:00程序设计版块每日发帖之星
日期:2015-09-24 06:20:00
发表于 2017-07-06 18:22 |显示全部楼层
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;

  4. my $count = my $content = '';
  5. while(<DATA>){
  6.         if(my $status = /aaa/ ... /bbb/){
  7.                 $content .= $_;
  8.                 $count = 1 if(/ccc/);
  9.                 next if($status !~ /E/);
  10.                 print($content) if($count);
  11.                 $count = $content = '';
  12.         }
  13. }

  14. __DATA__
  15. aaa
  16.   grge
  17.   ddd
  18. bbb

  19. aaa gege
  20. ccc
  21. bbb

  22. aaa gregeg
  23.   eee
  24. bbb
复制代码

论坛徽章:
0
发表于 2017-07-06 18:24 |显示全部楼层
1 不好意思,我是反正则派的      不用正则,自己写代码的方案,也不难。

2 打开一个文件,放入字符串。
3 找到 第一个 aaa,并记录位置,并记录一个找到了头的布尔值。
4 如果布尔值为真,就说明找到了aaa。那么就跳过3,执行4。4就是找到aaa后面第一个bbb。并记录位置。
5取两点之间的内容,判断是否含有ccc。有就另存。清除找到了头的布尔值。
6如此类推。

论坛徽章:
2
15-16赛季CBA联赛之八一
日期:2017-07-06 14:20:4715-16赛季CBA联赛之上海
日期:2017-08-21 22:14:34
发表于 2017-07-06 21:11 |显示全部楼层
本帖最后由 irockey 于 2017-07-06 23:47 编辑

awk '/aaa/{t=1}{if(t)s=length(s)?s"\n"$0:$0}/bbb/{t=0;if(s~/ccc/)print s;s=""}' file
其实我是这一段不懂什么意思,这个是六神之前的一个帖子的问题,我拿来研究的

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
发表于 2017-07-06 22:02 |显示全部楼层
回复 6# irockey


1. 三目运算符  ? :

s=   length(s)   ?    s"\n"$0   :   $0


if ( length(s) )
  s=   s"\n"$0
else
  s=  $0

论坛徽章:
2
15-16赛季CBA联赛之八一
日期:2017-07-06 14:20:4715-16赛季CBA联赛之上海
日期:2017-08-21 22:14:34
发表于 2017-07-06 22:52 |显示全部楼层
回复 7# jason680

谢谢一如既往的指导
其实  三目运算符  ? :   这个知识点我是知道的
但我一直没有搞清楚的是这个命令的识别,或者叫分段吧我开始是这样分段的s=length(s)这个为一个整体
s=length(s)   ?    s"\n"$0   :   $0

但后来发现有问题,但不确定;


这里是优先级的原因吗?

s=(length(s)   ?    s"\n"$0   :   $0)
这里加个()是不是更容易理解?

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
发表于 2017-07-06 23:34 |显示全部楼层
本帖最后由 jason680 于 2017-07-06 23:36 编辑

回复 8# irockey

个人理解方法:
X = Y
是Y的结果给X

不管Y是单一个或是多个(算法)....
都是 最后 结果 给X
也就是 X = ( Y )
X = a;           # X = ( a )
X = a==1;    #  X = ( a==1 )

论坛徽章:
0
发表于 2017-07-07 13:26 |显示全部楼层
回复 5# 本友会机友会摄友会

这个逼装得,啧啧。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP