免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6010 | 回复: 15
打印 上一主题 下一主题

perl循环多行匹配问题请教 [复制链接]

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-07-08 22:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-07-06 16:10 |显示全部楼层 |倒序浏览
我有一个包含几万行的log1文件,部分内容如下:

.......................
2015-7-6 15:30:06  BS7546152075910633343435A
2015-7-6 15:30:08  CAB753715207511043333333326
.......................
2015-7-6 15:30:16  CAB754615207511043333333321
.......................
2015-7-6 15:31:20  BS7538152075910633343435B
.......................
2015-7-6 15:31:31  CS7538152075110433333333B8
.......................

这些内容之间还包括了很多行
如果要打印出包含字符串"75(\d{6})75910633343435"的行和包含$1的行并保存到log2文件中,如这部分内容我要得到的行是:
2015-7-6 15:30:06  BS7546152075910633343435A
2015-7-6 15:30:16  CB754615207511043333333321
2015-7-6 15:31:20  BS7538152075910633343435B
2015-7-6 15:31:31  CS7538152075110433333333B8

用perl脚本怎么实现呢?


我刚开始是想着一步一步来,先实现打印出$1,程序如下:
use strict;
open(MYFILE,"E:/log1.txt") or die("Can't open log1.txt");
$/ = undef;
while(my $values1 = <MYFILE>){
    if($values1 =~ /75(\d{6})75910633343435/){
        print $1;
    }     
}
close MYFILE;

但得到的只有一个值:461520,我本来想得到的结果是
461520
381520

因为还在初学阶段,我是想着一步一步来,先实现打印出$1,再实现包含$1的行,不过研究了很久第一步还没有实现。小妹是初学perl,请大家多多指教,谢谢!

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-07-08 22:20:00
2 [报告]
发表于 2015-07-07 08:55 |显示全部楼层
请问应该如何实现打印出所有包含了$1(如包含461520和381520)的行?回复 2# rubyish


   

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-07-08 22:20:00
3 [报告]
发表于 2015-07-07 09:07 |显示全部楼层
本帖最后由 yilongyansha 于 2015-07-07 09:08 编辑

回复 2# rubyish

我写了一个程序,想实现打印所有包含$1的行,可是运行之后为空,什么都没有显示

use strict;
open(MYFILE,"E:/log1.txt") or die("Can't open log1.txt");
# local $/;
while(my $values1 = <MYFILE>){
    if($values1 =~ /75(\d{6})75910633343435/){
        if(my $values2 =~ /75($1)75/){
            print "$values2\n";
        }
    }     
}
close MYFILE;

   

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-07-08 22:20:00
4 [报告]
发表于 2015-07-07 10:00 |显示全部楼层
回复 6# xiaoxingan99

第一个问题解决了,谢谢!

第二个问题,$values2好像是没赋值,然后我改了一个程序:

use strict;
open(MYFILE,"E:/log1.txt") or die("Can't open log1.txt");
# local $/;
while(my $values1 = <MYFILE>){
    if($values1 =~ /75(\d{6})75910633343435/){
        while(my $values2 = <MYFILE>){
            if($values2 =~ /75($1)75/){
                print "$values2\n";
            }
        }
    }     
}
close MYFILE;

改程序之后结果也不对,只输出了
2015-7-6 15:30:16  CB754615207511043333333321

我想得到的输出是:
2015-7-6 15:30:06  BS7546152075910633343435A
2015-7-6 15:30:16  CB754615207511043333333321
2015-7-6 15:31:20  BS7538152075910633343435B
2015-7-6 15:31:31  CS7538152075110433333333B8
因为$1=381520也符合$values1的匹配

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-07-08 22:20:00
5 [报告]
发表于 2015-07-07 10:56 |显示全部楼层
回复 8# xiaoxingan99

我把$1赋值给$a再匹配,也重新赋值了一个文件句柄MYFILE1,但后面符合匹配的还是没有输出,比如$1=381520的就没有显示,只输出了

2015-7-6 15:30:06  BS7546152075910633343435A
2015-7-6 15:30:16  CB754615207511043333333321

   

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-07-08 22:20:00
6 [报告]
发表于 2015-07-07 11:09 |显示全部楼层
本帖最后由 yilongyansha 于 2015-07-07 11:12 编辑

回复 10# xiaoxingan99

use strict;
open(MYFILE1,"E:/log1.txt") or die("Can't open log1.txt");
open(MYFILE2,"E:/log1.txt") or die("Can't open log1.txt");
# $/ = undef;
while(my $values1 = <MYFILE1>){
    if($values1 =~ /75(\d{6})75910633343435/){
        $a = $1;
        while(my $values2 = <MYFILE2>){
            if($values2 =~ /75($a)75/){
                print "$values2\n";
            }
        }
    }     
}
close MYFILE1;
close MYFILE2;
   

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-07-08 22:20:00
7 [报告]
发表于 2015-07-07 11:52 |显示全部楼层
回复 12# xiaoxingan99

我的文件比较大,有几万行,按照你的程序运行,输出的大部分都重复输出了2次,比如输出的一部分为:


2015-7-6 15:30:06  BS7546152075910633343435A
2015-7-6 15:30:16  CB754615207511043333333321
2015-7-6 15:30:06  BS7546152075910633343435A
2015-7-6 15:30:16  CB754615207511043333333321
2015-7-6 15:31:20  BS7538152075910633343435B
2015-7-6 15:31:31  CS7538152075110433333333B8
2015-7-6 15:31:20  BS7538152075910633343435B
2015-7-6 15:31:31  CS7538152075110433333333B8

不知道出了什么问题

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-07-08 22:20:00
8 [报告]
发表于 2015-07-07 12:30 |显示全部楼层
回复 14# substr函数

先匹配字符串中有数字75,后面跟着6位数字\d{6}(如461520或者381520之类的数字),再后面是75910633343435数字的行,其中的$1=\d{6},满足这一条件后,在后面的行中匹配字符串中有数字75,后面跟着$1=\d{6} 6位数字,再后面是75数字的行,例如部分文件内容:

.......................
2015-7-6 15:30:06  BS7546152075910633343435A
2015-7-6 15:30:08  CAB753715207519043333333326
.......................
2015-7-6 15:30:16  CAB754615207511043333333321
2015-7-6 15:30:19  DC751564237514043333333389
.......................
2015-7-6 15:31:20  BS7538152075910633343435B
.......................
2015-7-6 15:31:31  FG7538152075110433333333B8
2015-7-6 15:31:31  FG7556163975150433333333B8
.......................

要得到的输出是:

2015-7-6 15:30:06  BS7546152075910633343435A
2015-7-6 15:30:16  CB754615207511043333333321
2015-7-6 15:31:20  BS7538152075910633343435B
2015-7-6 15:31:31  CS7538152075150433333333B8

   

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-07-08 22:20:00
9 [报告]
发表于 2015-07-07 13:42 |显示全部楼层
回复 16# xiaoxingan99

文件有3万行左右,而且基本上不会有两行一样的,但我输出的结果大部分都重复了一次,有些行的顺序也和原文件不同


   

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-07-08 22:20:00
10 [报告]
发表于 2015-07-07 13:50 |显示全部楼层
回复 18# substr函数

是的
不过匹配的这两行基本上不是一样的


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP