Localizando grupos de endereços IP em um arquivo

3

Eu tenho um arquivo com grupos de endereços IP. O arquivo é assim:

London:
1.1.1.0-1.1.1.200
172.25.2.0-172.25.2.100
Germany:
2.2.2.0-2.2.2.100
192.168.1.0-192.168.1.200
172.25.2.0-172.25.2.200

Então, quando eu procurar por um endereço IP ( ./program.sh 172.25.2.32 ), a saída deve ser Londres e Alemanha.

    
por user3523605 01.09.2014 / 09:44

3 respostas

2

Você não aceitou as outras soluções, talvez porque a saída delas não corresponda à "London and Germany" solicitada

O Modern Python pode lidar com endereços IP prontos para uso:

#! /usr/bin/env python3.4
# coding: utf-8
# also works on 2.7 after installing ipaddress from PyPI

import sys
from ipaddress import ip_address
print

ip_string = sys.argv[1]
if sys.version_info < (3,):
    ip_string = ip_string.decode('utf-8')

ip = ip_address(ip_string)

locs = []
for line in open('input'):
    try:
        loc, rest = line.split(':')
    except ValueError:
        try:
            if sys.version_info < (3,):
                sr, er = map(ip_address, [x.decode('utf-8') for x in line.rstrip().split('-')])
            else:
                sr, er = map(ip_address, line.rstrip().split('-'))
            if sr < ip < er:
                locs.append(loc)
        except ValueError:
            print 'error in input line:', repr(line)
            break

if len(locs) > 2:
    locs = [', '.join(locs[:-1]), locs[-1]]
print(' and '.join(locs))

Isso imprime os locais encontrados e coloca " and " entre os dois últimos locais encontrados e " , " entre todos os outros (quando aplicável): por exemplo, London, Paris and Germany

Supõe-se que os dados estejam em um arquivo chamado input , torne o script executável ou chame com python scriptname 172.25.2.32

    
por 06.09.2014 / 08:24
2

Neste caso, usar uma das muitas linguagens de programação de uso geral que estão normalmente disponíveis para o sistema Unix e Linux (como parte da instalação padrão ou através de uma simples instalação de pacotes) é provavelmente o mais fácil. Aqui está um exemplo de como você concluiria a tarefa usando Ruby:

#!/usr/bin/env ruby
require 'ipaddr'

ip = ARGV[0]
ARGV.delete(ip)
last_location = nil
ARGF.each do |line|
  if line.include?(':')
    last_location = line.chomp.gsub(/:/, "")
    next
  end

  first, last = line.chomp.split("-").map {|i| IPAddr.new(i).to_i }
  needle = IPAddr.new(ip).to_i
  if (first..last).include?(needle)
    puts "Found #{ip} in #{last_location}"
  end
end

Isto não é particularmente bom Ruby, mas é capaz de tirar proveito da biblioteca ipaddr para evitar a análise manual de endereços IP. Embora o processamento manual não seja um bom negócio em seu texto de exemplo, seria mais difícil quando você tinha intervalos como 172.25.2.0-172.25.3.200.

Sua pergunta está marcada com bash e text-processing . Se você está procurando uma resposta usando as ferramentas de processamento de texto mais amplamente disponíveis, como sed, awk e grep, então você pode querer apenas olhar para a estratégia geral contida no script ruby acima:

  1. Armazene o argumento de endereço IP em uma variável para facilitar o acesso posteriormente
  2. Leia cada linha do arquivo
  3. Determine se a linha é uma descrição de local ou intervalo de endereços IP.
  4. Se for uma descrição de local, armazene-a em last_location
  5. Se for um intervalo de endereços IP, determine se o seu IP está nesse intervalo
  6. Se o ip estiver no intervalo, imprima a variável last_location.

Não é a solução mais elegante, mas é simples de implementar em vários idiomas e seria fácil de entender por qualquer pessoa familiarizada com o idioma.

    
por 01.09.2014 / 12:04
2

perl versão de a resposta de Steven :

perl -MSocket -F- -lane '
  sub ip_to_n {unpack"N",inet_aton$_[0]}
  BEGIN {$i=ip_to_n(shift)}
  if (/:$/) {chop;$l=$_} else {
    print $l if $i >= ip_to_n($F[0]) && $i <= ip_to_n($F[1])
  }' 172.25.2.32 file1 file2...
    
por 01.09.2014 / 12:29