Perl однострочный лайнер + сопоставление IP-адреса

Я пытаюсь создать однострочный лайнер Perl, который точно соответствует IP-адресу из файла, и распечатать соответствующий IP-адрес.

если IP-адрес не совпадает, он не будет печатать IP-адрес.

ЗАМЕЧАНИЕ - слева / справа от IP-адреса [слева] xxx.xxx.xxx.xxx [справа] - может быть любой символ, но сам 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

person Community    schedule 28.12.2012    source источник


Ответы (2)


Для сопоставления общих шаблонов в этом случае вы можете обратиться к 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'
person JRFerguson    schedule 28.12.2012

Вам нужно удалить лишние части. Кроме того, вы должны избегать точек в $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 { 
        $_ = ""; 
    }'
person peterph    schedule 28.12.2012
comment
как написать свой код - Perl one line liner (потому что мне нужно добавить perl one liner в мой сценарий ksh) - person ; 28.12.2012
comment
проблема в том, что если IP = 23.45.7.00 или IP = 123.45.7.0, тогда он также распечатывает IP, в то время как он не должен печатать его, см. мои примеры в моем quastion - person ; 29.12.2012
comment
@Eytan, у меня работает, ты уверен, что где-то нет опечатки? - person peterph; 30.12.2012
comment
вот что я получаю от своих Linux-машин: # echo 23.45.7.00 | perl -e 'мой $ ip = quotemeta ($ ENV {IP}); ›While (‹ ›) {› next if (/ ^ * $ /); ›S /^.* ($ {ip}). * $ / $ 1 / && print; ›} '23.45.7.0, он напечатает ip = 23.45.7.0 - person ; 30.12.2012
comment
@Eytan, сценарий не интерпретирует числа - если вы установите IP=23.45.7.0 в среде сценария, не ожидайте, что он напечатает 23.45.7.00 (два конечных нуля вместо одного). - person peterph; 31.12.2012
comment
Я не это имел в виду - он напечатает 23.45.7.00, я имею в виду, что если IP-адрес не совпадает точно, то не нужно ничего печатать. - person ; 01.01.2013
comment
@Eytan нет, скрипт не печатает какую-либо часть строки, если в ней нет IP. - person peterph; 01.01.2013