跟踪路由日志到CSV Perl解析器正则表达式问题
我编写了一些shell脚本,它们运行到主机的跟踪路由,然后将它们保存到文件中。这项功能工作正常,并按预期将所有数据输出到跟踪路由日志到CSV Perl解析器正则表达式问题,perl,Perl,我编写了一些shell脚本,它们运行到主机的跟踪路由,然后将它们保存到文件中。这项功能工作正常,并按预期将所有数据输出到.log文件 然后,我编写了一个简单的Perl脚本,将此.log转换为.csv文件,以便将其导入excel。然而,在查看生成的.csv文件时,我编写的Perl脚本在处理带有IP地址的数据包时出现了问题 例如,.log文件中的这一行被完美解析: 1139.222.0.1 0.941毫秒1.446毫秒1.996毫秒 进入.csv文件,如下所示: 1139.222.0.1,0.941
.log
文件
然后,我编写了一个简单的Perl脚本,将此.log
转换为.csv
文件,以便将其导入excel。然而,在查看生成的.csv
文件时,我编写的Perl脚本在处理带有IP地址的数据包时出现了问题
例如,.log
文件中的这一行被完美解析:
1139.222.0.1 0.941毫秒1.446毫秒1.996毫秒
进入.csv
文件,如下所示:
1139.222.0.1,0.941毫秒,1.446毫秒,1.996毫秒
但是,如果traceroute返回存储在.log
文件中的与此类似的内容:
12154.54.57.98 7.579 ms 154.54.74.42 7.009 ms 130.117.0.58 7.480 ms
然后它被错误地解析到.csv
文件中,并破坏以下整个.csv
文件(这是一个虚构的示例):
11213.248.77.134,7.432毫秒,9.038毫秒,213.248.70.238毫秒
正如您所看到的,带有跃点时间的IP现在被用作数据包所用的时间
我很困惑如何解决这个问题!如果您有任何帮助,我们将不胜感激。下面是一段代码片段,它可以将每个跃点的日志转换为csv:
my $start = "'Hop','IP','T1','T2','T3'";
print OUTPUT "\n$_$start\n";
};
print OUTPUT "$1,$2,$3 ms,$4 ms,$5 ms\n" if (/(\d+)\s+(\S+)\s+(\S+)\s+ms\s+(\S+)\s+ms\s+(\S+)/);
编辑
编写了我自己的修复程序,添加了额外的csv列并适当地插入其中
my $start = "'Hop','IP','T1','T1IP','T2','T2IP',T3'";
print OUTPUT "\n$_$start\n";
};
if (/(\d+)\s+(\S+)\s+(\S+)\s+ms\s+(\S+)\s+ms\s+(\S+)\s+ms/){
print OUTPUT "$1,$2,$3 ms, ,$4 ms, ,$5 ms\n";
}elsif (/(\d+)\s+(\S+)\s+(\S+)\s+ms\s+(\S+)\s+(\S+)\s+ms\s+(\S+)\s+ms/){
print OUTPUT "$1,$2,$3 ms,$4,$5 ms, ,$6 ms\n";
}elsif (/(\d+)\s+(\S+)\s+(\S+)\s+ms\s+(\S+)\s+ms\s+(\S+)\s+(\S+)\s+ms/){
print OUTPUT "$1,$2,$3 ms, ,$4 ms,$5,$6 ms\n";
}elsif (/(\d+)\s+(\S+)\s+(\S+)\s+ms\s+(\S+)\s+(\S+)\s+ms\s+(\S+)\s+(\S+)\s+ms/){
print OUTPUT "$1,$2,$3 ms,$4,$5 ms,$6,$7 ms\n";
};
感谢您的帮助/回复 对于您显示的数据,我只需将行拆分为空格,后面不跟
ms
my $csv = join ',', split /\s+(?!ms)/, $line;
但是,您显示的代码暗示跟踪路由信息与日期混在一起,因此这可能不合适
更新
看过你的数据后,我认为这应该是你想要的
请注意,打印的标头名称与行中有多个IP地址的数据不对应。我不知道在那种情况下你想做什么
#!/usr/bin/perl
use strict;
use warnings;
use autodie;
my $logfile = 'trace.log';
my $parsedfile = 'trace.csv';
open my $infh, '<', $logfile;
open my $outfh, '>', $parsedfile;
while (<$infh>) {
if (/^[a-z]{3}\s+[a-z]{3}/i) {
print $outfh $_;
print $outfh qq{"Hop","IP","T1","T2","T3"\n};
}
elsif (/^\s*\d/) {
chomp;
s/^\s+//;
print $outfh join(',', split /\s+(?!ms)/), "\n";
}
}
猜测您想要什么,不带标题代码:
my $re_ip = qr/\d+\.\d+\.\d+\.\d+/;
while(<INPUT>) {
my @v = split(/($re_ip)/);
my $hop = (shift(@v) =~ /(\d+)/)[0]; # the hop number?
for my $v (@v) {
if ($v =~ /$re_ip/) {
print OUTPUT "$hop,$v,";
} else {
my @ms = $v =~ /(\S+\s+ms)/g;
print OUTPUT join(",", @ms), "\n";
}
}
}
my$re\u ip=qr/\d+\.\d+\.\d+\.\d+/;
while(){
my@v=拆分(/($re_ip)/);
我的$hop=(shift(@v)=~/(\d+/)[0];#跳数是多少?
我的$v(@v){
如果($v=~/$re\u ip/){
打印输出“$hop,$v”;
}否则{
my@ms=$v=~/(\S+\S+ms)/g;
打印输出联接(“,”,@ms),“\n”;
}
}
}
请显示不工作的代码如果(/(\d+)\s+(\s+)\s+(\s+)\s+(\s+)\s+(\s+)\s+(\s+)\s+(\s+)\s+ms+(\s+),则不工作的代码为打印输出“$1、$2、$3 ms、$4 ms、$5 ms\n”;因为这只解释了如果跟踪路由只返回时间值,而不返回时间和IP值,那么日期只是作为标题,并且在日志/csv文件的开头只打印一次,因为此跟踪路由重复运行,我需要它作为参考,traceroute启动后,将不会打印其他日期:)谢谢您的回复,我将研究该方法谢谢您更好地理解了您的问题,我认为我的解决方案可能不合适。一个完整输入的示例将很有帮助。谢谢Ben。我已经更新了我的答案,以提供我认为有效的程序这正是我一直在尝试的,我使用一系列elsif语句创建了一个类似的程序,但是这只起了一半的作用,您的代码更整洁、更容易理解。非常感谢你!还添加了我自己对原始问题的回答,以处理标题问题:)再次感谢!谢谢你的回复,我也来看看这个:)
my $re_ip = qr/\d+\.\d+\.\d+\.\d+/;
while(<INPUT>) {
my @v = split(/($re_ip)/);
my $hop = (shift(@v) =~ /(\d+)/)[0]; # the hop number?
for my $v (@v) {
if ($v =~ /$re_ip/) {
print OUTPUT "$hop,$v,";
} else {
my @ms = $v =~ /(\S+\s+ms)/g;
print OUTPUT join(",", @ms), "\n";
}
}
}