我正在使用Perl脚本,用户从命令行运行tracert并从cli复制并在perl CGI脚本中提交tracert&我的脚本将tracert保存为文件。
然后我一次打开一行文件并通过Perl Regex grep获取ip地址。
问题是:有时用户跟踪某些跳跃的结果变得太大,下面是一个示例,IP地址分为两部分(使用CR& LF),因此我的正则表达式匹配失败。
4 2 ms 1 ms 1 ms routers.static-ABC.XYZ.net.in [165
.112.109.61]
我正在寻找一些解决方案,要么我可以移除文件的所有白色和其他空间,要么得到一个我可以匹配的正则表达式和中间的IP地址(使用CR& LF)两行。
如果我能以某种方式让我的程序搜索"]"在文件中,如果我找不到这个,并且在行的末尾有一个空格(CR& LF),则删除空格并加入该行。这将解决我的问题。
以下是脚本的一部分:
my @array;
open(my $fh, "<", "trace.txt")
or die "Failed to open file: $!\n";
while(<$fh>) {
&match_ip($_); ##match_ip(@array);
}
close $fh;
sub match_ip()
{
if($_ =~ m/([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/g)
{
$ip = "$1\.$2\.$3\.$4";
print "$ip\n";
}
}
答案 0 :(得分:1)
它只发生在点上吗?在这种情况下,你可以这样做:
if($_ =~ m/([0-9]{1,3})\s*\.\s*([0-9]{1,3})\s*\.\s*([0-9]{1,3})\s*\.\s*([0-9]{1,3})/g)
{
$ip = "$1\.$2\.$3\.$4";
print "$ip\n";
}
或者,你也可以研究IP出现在方括号之间的事实(如果是这种情况就像你展示的那样;如果没有,你仍然可以这样做,但最后过滤掉非IP):
$_ =~ /\[(.*?\s*?.*?)\]/; # extract everything between square brackets
my $ip = $1; # take that IP
$ip =~ s/\s//g; # remove possible white spaces from the IP
答案 1 :(得分:0)
如果您逐行循环遍历文件并且IP分为两行,则所提议的正则表达式解决方案都不起作用。您可以在段落模式下读取数据,在这种情况下,所有跃点都将在一个字符串中。
就个人而言,我可能会以不同的方式看待这一点。我将这条线拆分成一个数组。 Windows tracert命令为每个跃点使用8到9个字段。如果数组少于8个字段,那么行是&#34;包裹&#34;并且应该在解析IP之前添加到上一行。这种方法需要您一次处理2行,以确定换行并将行重新连接在一起。
答案 2 :(得分:0)
逐行解决方案:
#!/usr/bin/perl
use strict;
use warnings;
while(<DATA>) {
if (/(\d+(?:\.\d+){3})]$/) {
print $1 . "\n";
} else {
my $tmp;
if (/\[([\d.]+)$/) {
$tmp = $1;
} else { next; }
while(<DATA>) {
if (/([\d.]+)]$/) {
$tmp .= $1;
print $tmp . "\n";
last;
} elsif (/([\d.]+)$/) {
$tmp .= $1;
}
}
}
}
__DATA__
1 24 ms 22 ms 22 ms 1.32.202.62.cust.bluewin.ch [62.202.32.1]
2 22 ms 24 ms 22 ms 1.32.202.62.cust.bluewin.ch [62.202.32.1]
3 24 ms 23 ms 22 ms net481.bwrt2zhb.bluewin.ch [195.186
.121.1]
4 314 ms 162 ms 22 ms net125.bwrt1inb.bluewin.ch [195.186.125.71]
5 34 ms 23 ms 24 ms if114.ip-plus.bluewin.ch [195.186.0.114]
6 27 ms 29 ms 29 ms i68geb-005-gig4-2.bb.ip-plus.net [138.1
87.1
30.158]
7 39 ms 39 ms 38 ms i00par-005-pos4-0.bb.ip-plus.net [138.187.129.34]
8 38 ms 320 ms 39 ms feth2-kara-ielo.freeix.net [213.228.3.203]
9 284 ms 39 ms 39 ms feth0-bestelle.tlcy.fr.core.ielo.net [212.85.144.6]
10 90 ms 158 ms 83 ms chloe.wikimedia.org [212.85.150.132]
答案 3 :(得分:0)
由于它是一个小文件,因此请考虑在整个文件中进行啜食,全局捕获[
和]
之间的所有IP,然后删除这些捕获中的任何空格。下面的子例程getIPsFromFile
执行此操作:
use strict;
use warnings;
my @IPs = getIPsFromFile('trace.txt');
print "$_\n" for @IPs;
sub getIPsFromFile {
my ($file) = @_;
my $contents = do {
local $/;
open my $fh, '<', $file or die $!;
<$fh>;
};
return map { s/\s+//g; $_ } $contents =~ /\[(.+?)\]/gs;
}
希望这有帮助!
答案 4 :(得分:0)
似乎每个跃点的tracert
输出始终以间距开头,后跟跳数,后跟更多间距。即使有包装,也可以用它来表示跳跃的开始,因为没有包裹将有一个由间距包裹的数字。
在该行的另一端,ip地址将是最后一个条目,它可能会也可能不会被括号[]括起来。此外,ip实际上可能只是说“请求超时”。
鉴于此信息,我构建了适用于ipv4和ipv6数据的脚本:
use strict;
use warnings;
my $hop = '';
while (<DATA>) {
chomp;
# Start or End of new hop
if ((my $startHop = $_ =~ /^\s+\d+\s+/) || /Trace complete./) {
if ($hop =~ /^\s+(\d+).*\s\[?(\S+?)\]?$/) {
print "IP = $1 - $2\n";
}
$hop = $startHop ? $_ : '';
} elsif ($hop) {
$hop .= $_;
}
}
if ($hop =~ /^\s+(\d+).*\s\[?(\S+?)\]?$/) {
print "IP = $1 - $2\n";
}
__DATA__
Tracing route to ds-any-fp3-real.wa1.b.yahoo.com [98.138.253.109]
over a maximum of 30 hops:
1 3 ms 1 ms 1 ms READYSHARE [192.168.1.1]
2 33 ms 27 ms 29 ms c-67-164-32-1.hsd1.ca.comcast.net [67.164.32.1]
3 16 ms 11 ms 10 ms te-7-6-ur02.oakland.ca.sfba.comcast.net [68.85.2
17.169]
4 13 ms 12 ms 11 ms te-0-2-0-6-ar01.oakland.ca.sfba.comcast.net [68.
87.194.230]
5 13 ms 15 ms 21 ms be-100-ar01.sfsutro.ca.sfba.comcast.net [68.85.1
55.18]
6 22 ms 31 ms 24 ms he-3-8-0-0-cr01.sanjose.ca.ibone.comcast.net [68
.86.94.85]
7 25 ms 23 ms 23 ms 50.242.148.34
8 86 ms 87 ms 86 ms vlan90.csw4.SanJose1.Level3.net [4.69.152.254]
9 111 ms 92 ms 84 ms ae-92-92.ebr2.SanJose1.Level3.net [4.69.153.29]
10 118 ms 85 ms 86 ms ae-3-3.ebr1.Denver1.Level3.net [4.69.132.58]
11 89 ms 262 ms 85 ms ae-1-100.ebr2.Denver1.Level3.net [4.69.151.182]
12 88 ms 92 ms 86 ms ae-3-3.ebr1.Chicago2.Level3.net [4.69.132.62]
13 87 ms 91 ms 88 ms ae-1-51.edge3.Chicago3.Level3.net [4.69.138.136]
14 92 ms 87 ms 115 ms YAHOO-INC.edge3.Chicago3.Level3.net [4.53.96.158
]
15 105 ms 102 ms 104 ms ae-7.pat1.nez.yahoo.com [216.115.104.124]
16 117 ms 120 ms 101 ms ae-1.msr1.ne1.yahoo.com [216.115.100.5]
17 177 ms 103 ms 108 ms xe-7-0-0.clr2-a-gdc.ne1.yahoo.com [98.138.0.27]
18 104 ms 104 ms 103 ms et-18-25.fab7-1-gdc.ne1.yahoo.com [98.138.93.11]
19 112 ms 104 ms 104 ms po-16.bas2-7-prd.ne1.yahoo.com [98.138.240.34]
20 104 ms 185 ms 114 ms ir1.fp.vip.ne1.yahoo.com [98.138.253.109]
Trace complete.
##########
Tracing route to www.google.com [2607:f8b0:4003:c06::68]
over a maximum of 30 hops:
1 466 ms 311 ms 132 ms dsldevice6.att.net [2602:301:7766:d3a0:5ccc:b9ff
:fedb:9ea0]
2 275 ms * 240 ms 2602:300:c533:1510::6
3 101 ms 469 ms 254 ms sj2ca405me3.ipv6.att.net [2001:1890:ff:ffff:12:1
22:119:193]
4 * * * Request timed out.
5 93 ms 45 ms 59 ms 2001:4860::1:0:7ea
6 363 ms 72 ms 53 ms 2001:4860::8:0:6117
7 292 ms 224 ms 189 ms 2001:4860::8:0:3427
8 99 ms 77 ms * 2001:4860::8:0:2c9d
9 251 ms 167 ms 246 ms 2001:4860::8:0:64c7
10 196 ms 274 ms 248 ms 2001:4860::2:0:5bab
11 * * * Request timed out.
12 270 ms 202 ms 362 ms 2607:f8b0:4003:c06::68
输出
IP = 1 - 192.168.1.1
IP = 2 - 67.164.32.1
IP = 3 - 68.85.217.169
IP = 4 - 68.87.194.230
IP = 5 - 68.85.155.18
IP = 6 - 68.86.94.85
IP = 7 - 50.242.148.34
IP = 8 - 4.69.152.254
IP = 9 - 4.69.153.29
IP = 10 - 4.69.132.58
IP = 11 - 4.69.151.182
IP = 12 - 4.69.132.62
IP = 13 - 4.69.138.136
IP = 14 - 4.53.96.158
IP = 15 - 216.115.104.124
IP = 16 - 216.115.100.5
IP = 17 - 98.138.0.27
IP = 18 - 98.138.93.11
IP = 19 - 98.138.240.34
IP = 20 - 98.138.253.109
IP = 1 - 2602:301:7766:d3a0:5ccc:b9ff:fedb:9ea0
IP = 2 - 2602:300:c533:1510::6
IP = 3 - 2001:1890:ff:ffff:12:122:119:193
IP = 4 - out.
IP = 5 - 2001:4860::1:0:7ea
IP = 6 - 2001:4860::8:0:6117
IP = 7 - 2001:4860::8:0:3427
IP = 8 - 2001:4860::8:0:2c9d
IP = 9 - 2001:4860::8:0:64c7
IP = 10 - 2001:4860::2:0:5bab
IP = 11 - out.
IP = 12 - 2607:f8b0:4003:c06::68
注意,偶尔ip显示为“out”。这是因为请求超时了。