Expressão regular no Bash para validar o endereço IP

4

No meu script Python, eu tenho uma expressão regular para procurar endereços IP como 0.0.0.0-255.255.255.255 em um arquivo, parece com isso:

[1-2]{0,1}[0-9]{0,1}[0-9]{1}\.[1-2]{0,1}[0-9]{0,1}[0-9]{1}\.[1-2]{0,1}[0-9]{0,1}[0-9]{1}\.[1-2]{0,1}[0-9]{0,1}[0-9]{1}

Agora eu preciso ter o mesmo em um script Bash. Então eu mudei assim:

[1-2]\{0,1\}[0-9]\{0,1\}[0-9]\{1\}\.[1-2]\{0,1\}[0-9]\{0,1\}[0-9]\{1\}\.[1-2]\{0,1\}[0-9]\{0,1\}[0-9]\{1\}\.[1-2]\{0,1\}[0-9]\{0,1\}[0-9]\{1\}

Funciona quase bem, mas, por algum motivo, filtra endereços como "1000.0.0", "2323.23.23.2323" e assim por diante. Por que isso acontece?

    
por Nervosa 31.01.2014 / 11:48

4 respostas

4

A python regexp está usando a sintaxe de expressão regular estendida que vem do comando egrep nos anos 70 (embora a parte {...} tenha sido adicionada posteriormente e, na verdade, em grep antes de egrep ). / p>

O POSIX consolidou os comandos grep e egrep ( egrep é agora grep -E ) nos anos 90 e padronizou o operador {x,y} (que não estava disponível no egrep s anterior).

Então, agora, você deve poder usar grep -E 'that-regexp' com todas as implementações grep modernas.

Observe que seu regexp permitiria 299.299.299.299 e o {1} s seria redundante. {0,1} pode ser reduzido para ? .

Observe que grep localizam linhas que correspondem ao regexp, ou seja, linhas que contêm uma string que corresponde ao regexp em qualquer lugar. Use ^ e $ para ancorar ou use a opção -x para grep .

    
por 31.01.2014 / 12:07
5

Tentou encurtar o regexp, aqui está o resultado:

#!/bin/bash

rx='([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])'

for ip in 08.08.08.08 3.3.3.3 11.11.11.11 \
      111.123.11.99 \
      222.2.3.4 999.88.9.9 \
      255.255.255.255 255.0.3.3 0.256.0.222; do

   if [[ $ip =~ ^$rx\.$rx\.$rx\.$rx$ ]]; then
      echo "valid:     "$ip
   else
      echo "not valid: "$ip
   fi
done
    
por 31.01.2014 / 13:33
2

Eu acho que isso deve cobrir isso

$ octet="(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])"

Ou para evitar zeros à esquerda:

$ octet="(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])"  

Você pode usar $octet :

$ ip4="^$octet\.$octet\.$octet\.$octet$"
$ echo $ip4
^(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$
$ [[ 123.234.12.34 =~ $ip4 ]] && echo y || echo n
y
$ [[ 123.234.12.345 =~ $ip4 ]] && echo y || echo n
n
    
por 31.01.2014 / 13:45
0

você pode integrar esta função com seu código para validar o endereço IP. Se você puder compartilhar seu código atual, posso ser mais específico para o problema.

function validateIP()
 {
         local ip=$1
         local stat=1
         if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
                OIFS=$IFS
                IFS='.'
                ip=($ip)
                IFS=$OIFS
                [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
                && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
                stat=$?
        fi
        return $stat
}

echo "Enter IP Address"
read ip
validateIP $ip

if [[ $? -ne 0 ]];then
  echo "Invalid IP Address ($ip)"
else
  echo "$ip is a Perfect IP Address"
fi
    
por 31.01.2014 / 12:34