linux + corresponde apenas a VALID IP do arquivo de texto em outro arquivo

2

por favor, informe como combinar apenas os IPs válidos (255.255.255.255) do arquivo.txt e insira apenas o IP válido no arquivo VALID_IP.txt

  • (consulte VALID_IP.txt por exemplo)

a solução deve ser implementada no meu script ksh (então perl ou sed ou awk também são bons)

mais arquivo.txt

     e32)5.500.5.5*kjcdr
     ##@$1.1.1.1+++jmjh
     1.1.1.1333
     33331.1.1.1
     @5.5.5.??????
     ~3de.ede5.5.5.5
     1.1.1.13444r54
     192.9.30.174
     &&^#%5.5.5.5
     :5.5.5.5@%%^^&*
     :5.5.5.5:
     **22.22.22.22
     172.78.0.1()*5.4.3.277

exemplo de arquivo VALID_IP.txt

     1.1.1.1
     192.9.30.174
     5.5.5.5
     5.5.5.5
     5.5.5.5
     22.22.22.22
     172.78.0.1
    
por yael 15.11.2012 / 09:27

3 respostas

4

O seguinte é um regex adequado, dividido em 4 linhas diferentes para minha própria sanidade.

(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.
(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.
(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.
(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])

Saída:

egrep -o 'cat regex' infile #all regex lines above joined, no spaces

1.1.1.1
1.1.1.133
31.1.1.1
5.5.5.5
1.1.1.134
192.9.30.174
5.5.5.5
5.5.5.5
5.5.5.5
22.22.22.22
172.78.0.1
5.4.3.27

Obviamente, isso não corresponde ao seu exemplo. Por quê? Porque não podemos dizer que um 3 não pertence a um. Como você pode ver, os números de lixo não podem ser facilmente adivinhados.

    
por 15.11.2012 / 09:49
3

É um pouco mais limpo com perl

#!/usr/bin/perl
use Regexp::Common qw/net/;
while (<>) {
      print $1, "\n" if /($RE{net}{IPv4})/;
}

mas ainda recebe falsos positivos

1.1.1.1
1.1.1.133
31.1.1.1
5.5.5.5
1.1.1.134
192.9.30.174
5.5.5.5
5.5.5.5
5.5.5.5
22.22.22.22
172.78.0.1

Perl one liner

perl -e 'use Regexp::Common qw/net/;while (<>) {print $1, "\n" if /($RE{net}{IPv4})/;}' infile
    
por 15.11.2012 / 10:24
2

Eu recomendo usar a verificação de intervalo em vez de regexes peludas. Você pode fazer isso em ksh sem usar um utilitário externo ou outro idioma. Embora a solução de Iain seja boa, não é um módulo central.

Aqui está o ksh puro. Não há necessidade de torná-lo um one-liner, apenas use uma função. Código como este é mais fácil de entender, mais fácil de verificar se é correto e mais fácil de manter.

#!/usr/bin/ksh
validate_ip () {
    typeset ip=$@
    typeset IFS=. valid=1
    typeset octets=($ip) octet
    typeset digits='^[[:digit:]]+$'

    if (( ${#octets[@]} == 4 ))
    then
        for ((octet = 0; octet <= 3; octet++))
        do
            value=${octets[octet]}
            if [[ ! "$value" =~ $digits ]] || ((value < 0 || value > 255))
            then
                valid=0
            fi
        done
    else
        valid=0
    fi

    if ((valid))
    then
        printf '%s\n' "$ip"
    fi

    return $valid
}

while read -r line
do
    validate_ip "$line"
done #< file.txt > VALID_IP.txt

Isso é ksh 93, eu não testei no ksh 88. Ele também roda inalterado no Bash 3.2 ou superior.

    
por 15.11.2012 / 14:43