Perl one line liner +匹配IP地址

时间:2012-12-28 12:25:20

标签: linux perl shell ksh

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

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

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

问题在于,无论我在回声后放置什么,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

2 个答案:

答案 0 :(得分:1)

你需要剥离多余的部分。另外,你应该逃避$IP中的点,以便它不匹配,例如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 { 
        $_ = ""; 
    }'

答案 1 :(得分: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'