Como verificar se algum endereço IP está presente em um arquivo usando scripts de shell?


13

Eu tenho um script que gera alguma saída. Quero verificar essa saída para qualquer endereço IP como

159.143.23.12
134.12.178.131
124.143.12.132

if (IPs are found in <file>)
then // bunch of actions //
else // bunch of actions //

É fgrepuma boa ideia?

Tenho bash disponível.


uso grep, egrep, awk ou sed, seja qual for u como
Ijaz Ahmad Khan

Você poderia ajudar com a sintaxe, por favor? Quero dizer, como ele procura um IP aleatório. Como descrever o padrão? Eu estaria procurando por qualquer endereço IP, não um endereço específico.
Koshur

5
Isso é apenas endereços IPv4 em notação quad-decimal? Eles poderiam ser escritos assim 0010.0000.0000.0001? Caso contrário, o arquivo pode conter itens que se parecem com endereços IP, como números de versão ( soft-1.2.1100.1.tar.gz, especificações de rede (10.0.0.0/24), 1.2.3.4.5)? Você aceitaria uma solução positiva em 333.444.555.666? Ou 0377.0377.0377.0377(um endereço IP quad-octal válido)?
Stéphane Chazelas

Se bashestiver disponível, então awknormalmente é também, por isso, este trabalho poder para você: awk '/([0-9]{2,3}\.){3}/ {print $5 "\t" $1}'(Este one-liner traduz a saída do anfitrião lista XFR para /etc/hostsformato.)
Mark Hudson

Respostas:


25

Sim, você tem muitas opções / ferramentas para usar. Eu apenas tentei isso, funciona:

ifconfig | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"

para que você possa usar grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"para saudar os endereços IP da sua saída.


Obrigado. Isso funciona. Você pode explicar um pouco? Esta é uma expressão regular?
Koshur

Sim, esta é uma expressão regular usada no bash com grep, você está apenas procurando por um padrão de três dígitos separados por pontos. você pode jogar com mudando os números em {1,2} para 2 dígitos consecutivos e assim por diante
Ijaz Ahmad Khan

Um pode também usar "\b([0-9]{1,3}\.){3}[0-9]{1,3}\/[0-9][0-9]?"para encontrar CIDRs (assumindo que eles são válidos)
vikas027

2

iniciando minha resposta com base nesta resposta:

Sim, você tem muitas opções / ferramentas para usar. Eu apenas tentei isso, funciona:

ifconfig | grep -oE "\ b ([0-9] {1,3}.) {3} [0-9] {1,3} \ b" a para que você possa usar grep -oE "\ b ([0- 9] {1,3}.) {3} [0-9] {1,3} \ b "para receber os endereços IP da sua saída.

e convertendo a resposta em IPv6 completo, etc ...:

fgrep -oE "\b([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}\b" -- file

se você quiser manter o / nnn se estiver lá:

fgrep -oE "\b([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}(/[0-9]{1,3}){0,1}\b" -- file

e também há a versão abreviada do IPv6 que inclui '::'.

Para obter mais respostas IPv6, você pode procurar aqui: /programming/53497/regular-expression-that-matches-valid-ipv6-addresses


fgrepé o nome antigo de uma variante grepque ignora a correspondência de padrões. Eu recomendo que você use grep(ou até mesmo egrep), especialmente porque você está claramente querendo a correspondência de padrões.
roaima 18/07/2016

2

Se o seu arquivo for chamado, por exemplo, ipsvocê pode escrever algo como:

while read -r ip
    do
        if [[ $ip == "$1" ]]; then
            shift
            printf '%s\n' 'action to take if match found'
        else
            printf '%s\n' 'action to take if match not found'
        fi
    done < ips

Então você pode passar os parâmetros como segue o script

./myscript 159.143.23.12 134.12.178.131 124.143.12.132 124.143.12.132

0

Se você possui a lista de IPs em um arquivo, um por linha, grepjá possui a -fopção conveniente :

$ man fgrep | grep file= -A1
       -f FILE, --file=FILE
              Obtain patterns from FILE, one per line.  The empty file contains zero patterns, and therefore matches nothing.  (-f is specified by POSIX.)

Isso pode causar alguns falsos positivos devido a seqüências de caracteres opcionalmente seguidas por outro número para torná-lo um IP diferente. Muitas coisas que você pode fazer sobre isso, dependendo do seu caso, você pode ou não decidir se preocupar.


0

Testado no SmartOS (uma variante do Solaris), esperamos que funcione em outros ambientes * nix:

egrep '(([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])'

Exemplo:

$ cat >file.txt
IP1: 192.168.1.1
IP2: 261.480.201.311
IP3: 1012.680.921.3411

$ egrep '(([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])' file.txt
IP1: 192.168.1.1

Esse padrão corresponde apenas ao IPv4 válido , ou seja, x.x.x.xonde xvaria de 0 a 255. Se você precisar extrair apenas o IP correspondente, adicione uma -oopção ao comando acima. Você pode incorporar esse comando em um script bash e, presumivelmente, em outros scripts shell também. E seegrep falhar,try grep -E ...

Utilizando-o em um script shell (bash):

ip=$(egrep -o '(([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])' file.txt) echo $ip


0

Acho que minha resposta para outro post é mais adequada aqui. Graças a este post e a outros, eu vim com isso, que procura o formato IP correto e depois se livra de todas as linhas que contêm 256 ou superior. Substitua o IP por algo inválido para não ver saída:

echo '255.154.12.231' | grep -E '(([0-9]{1,3})\.){3}([0-9]{1,3}){1}' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]'

O primeiro grep provavelmente foi encontrado nesta postagem e verifica se há números de 0 a 999 no formato XXXX

O segundo grep remove linhas com números 256-999, deixando apenas IPs de formato válidos, então pensei

MAS ... Como apontado pelo G-Man, eu estava errado ao assumir que o IP estaria em sua própria linha. Na maioria das vezes, porém, haverá um espaço ou outro divisor para procurar nos dois lados do IP. Os espaços / divisores podem ser removidos com sed ou outros meios depois que o IP for encontrado. Também adicionei -o ao primeiro grep:

echo ' 1234.5.5.4321 ' | grep -Eo ' (([0-9]{1,3})\.){3}([0-9]{1,3}){1} ' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]' | sed 's/ //'

echo ' 234.5.5.432 ' | grep -Eo ' (([0-9]{1,3})\.){3}([0-9]{1,3}){1} ' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]' | sed 's/ //'

O primeiro não dará saída, enquanto o segundo fornece e os espaços são removidos.


Suponha que eu tenha 500 endereços, variando de 10.0.0.1 a 10.0.1.244. Seu segundo grepjogaria fora essa linha por causa dos "500". (A pergunta nunca disse que os endereços IP no arquivo, se houver, estariam em uma linha por si mesmos.) Por outro lado, ele aceitará 1234.1.1.1 e 1.1.1.1234. Mas além disso, nada mal.
G-Man Diz 'Reinstate Monica'

-1

Redirecione essa saída para alguns outputFile

Simplesmente grepcom padrão como,

grep -sE "159.143.23.12|134.12.178.131|124.143.12.132" <outputFile>

4
Note-se que .é um operador de expressão regular e precisa escapar para que ela seja tratada literalmente
Stéphane Chazelas

1
Esses não são padrões, são literais. Não é uma resposta útil, pois o OP especificou "qualquer IP".
Mark Hudson

-1
ip -4  addr show eth1 |  grep -oP '(?<=inet\s)\d+(\.\d+){3}'
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.