3

我正在尝试构建
与文件中的 IP 地址完全匹配的 Perl 一行衬里,并打印匹配的 IP

如果 IP 不匹配,则不会打印 IP 地址。

备注 - 在 IP 地址的左侧/右侧 [left]xxx.xxx.xxx.xxx[right] - 可以是任何字符,但 IP 本身必须完全匹配

问题是不管我在 echo 之后放了什么,Perl 无论如何都会打印任何字符串

请指教我的语法有什么问题?

一些例子

     # export IP=23.45.7.0

应该匹配IP

      # echo 23.45.7.0 | perl  -pe 'next if /^*#/;/(\b|\D)$ENV{IP}(\b|\D)/'
        23.45.7.0

不应该匹配IP

       # echo 123.45.7.0 | perl  -pe 'next if /^ *#/; /(\b|\D)$ENV{IP}(\b|\D)/'
         123.45.7.0

应该匹配IP

     # echo IP23.45.7.0IP | perl -pe 'next if /^ *#/; /(\b|\D)$ENV{IP}(\b|\D)/'
       IP23.45.7.0IP

不应该匹配IP

       # echo 23.45.7.00 | perl  -pe 'next if /^ *#/; /(\b|\D)$ENV{IP}(\b|\D)/'
         23.45.7.00
4

2 回答 2

1

你需要去掉多余的部分。另外,您应该转义 the 中的点$IP,使其与 eg 不匹配23x45y7z0。例如像这样:

#!/usr/bin/perl
use strict;

my $ip = quotemeta($ENV{IP});

while (<>) {
    next if (/^ *$/);
    # try to replace everything by just the IP,
    # print if the line matched
    s/^.*(${ip}).*$/$1/ && print;
}

一个丑陋的“单行”(删除新行以减少实际行数和可读性):

perl -e 'my $ip = quotemeta($ENV{IP});
    while (<>) {
        next if (/^ *$/);
        s/^.*(${ip}).*$/$1/ && print;
    }'

似乎在-p这里造成了麻烦,因为如果解析的行不匹配,它就会打印出来(请参阅man perlrun解释)。您可以防止这种情况,例如:

perl -pe 'my $ip = quotemeta($ENV{IP});
    next if (/^ *$/);
    if (s/^.*(${ip}).*$/$1/) {
        print;
    } else { 
        $_ = ""; 
    }'
于 2012-12-28T13:02:02.113 回答
1

对于匹配常见模式,您可以查看Regexp::Common在这种情况下,特别是Regexp::Common::net.

根据您的规格:

echo 10.11.12.13|perl -MRegexp::Common=net -nE '$_=~/^$RE{net}{IPv4}{-keep}$/ and say $1'

10.11.12.13

...而此无效地址不匹配:

echo 10.11.1200.13|perl -MRegexp::Common=net -nE '$_=~/^$RE{net}{IPv4}{-keep}$/ and say $1'
于 2012-12-28T15:03:24.387 回答