在日常处理日志文件或网络数据时,经常会遇到需要从一大段文字中找出ref="/tag/849/" style="color:#EB6E00;font-weight:bold;">IP地址的情况。比如查看服务器访问日志,想快速定位某个请求来源的IP,手动翻找效率太低。这时候,用Perl配合正则表达式就能一键提取。
基本思路:匹配IPv4格式
常见的IP地址是IPv4格式,由四个0到255之间的数字组成,用点号分隔,比如192.168.1.1。我们可以用Perl写一个简单的正则来匹配这种结构。
#!/usr/bin/perl\nmy $text = \"访问来自192.168.1.1,另一个请求来自10.0.0.254,非法IP如300.200.100.50需要注意\";\nwhile ($text =~ /(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})/g) {\n my $ip = $1;\n if ($ip =~ /^\\d+\\.\\d+\\.\\d+\\.\\d+$/ && \n (split /\\./, $ip) == 4 && \n !grep { $_ > 255 } split /\\./, $ip) {\n print \"找到有效IP: $ip\n\";\n }\n}
上面这段脚本先用正则抓出所有形似IP的字符串,再进一步判断每一段是否都在0-255之间,排除像300.200.100.50这样的无效地址。
封装成小工具更方便
如果经常要处理这类任务,可以把逻辑做成一个可复用的脚本。比如把要分析的文本文件作为参数传入:
#!/usr/bin/perl\nuse strict;\nuse warnings;\n\nmy $filename = $ARGV[0];\nopen my $fh, '<', $filename or die \"无法打开文件: $!\";\n\nwhile (my $line = <$fh>) {\n chomp $line;\n while ($line =~ /(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})/g) {\n my $ip = $1;\n next if grep { $_ > 255 } split /\\./, $ip;\n print \"$ip\n\";\n }\n}\n\nclose $fh;
保存为 extract_ip.pl 后,运行 perl extract_ip.pl access.log 就能快速输出所有合法IP。这种小脚本在排查异常登录、统计访问来源时特别实用。
也可以匹配日志中的特定行
有时候不只是要IP,还想看到IP所在的完整日志行。可以调整匹配范围:
while (<$fh>) {\n print if /(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})/ && \n !grep { $_ > 255 } split /\\./, $1;\n}
这样整行内容都会被输出,便于结合上下文分析问题。比如在整理会议记录文档时,若其中夹杂了远程接入信息,也能快速筛出相关条目。