当记者问到匹配的IP地址,许多人会写
/\d+\.\d+\.\d+\.\d+/
,但是这会给误报。在Jeffrey Friedl的Mastering Regular Expressions中,作者给出了一个更加小心的IP地址匹配模式。下面的代码借用了Friedl强制的不是任意的数字运行,而是从0到255的范围,要求地址开始和结束在字边界(\b),并且不允许地址0.0.0.0。
没有参数时,下面的代码默认为当前目录作为搜索开始。要搜索所有文件,请提供根目录作为参数。打开find输出的每条路径,然后我们搜索每条线路的IP地址并打印所有匹配以及它们各自的路径。
请注意代码如何使用local在记录分隔符$/的NUL字符和换行符之间来回切换。这是必要的,因为find的-print0操作将文件名与分开,但'\n'是行终止符。用-T,我们只搜索文本文件。
#! /usr/bin/perl
use warnings;
no warnings 'exec';
use strict;
my $octet = qr/[01]?\d\d?|2[0-4]\d|25[0-5]/;
my $ip = qr/ \b
(?!0+\.0+\.0+\.0+\b)
$octet(?:\.$octet){3}
\b
/x;
@ARGV = (".") unless @ARGV;
open my $find, "-|", "find", @ARGV, "-type", "f", "-print0"
or die "$0: failed to start find: $!\n";
$/ = "\0";
while (defined(my $path = )) {
chomp $path;
next unless -T $path;
if (open my $fh, "
local $/ = "\n";
while () {
print "$path: $_" if /$ip/;
}
close $fh;
}
else {
warn "$0: open $path: $!\n";
}
}