在文件中查找 IP 地址组

在文件中查找 IP 地址组

我有一个包含 IP 地址组的文件。该文件如下所示:

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

因此,当我搜索 IP 地址 ( ./program.sh 172.25.2.32) 时,输出应该是伦敦和德国。

答案1

您尚未接受其他解决方案,可能是因为它们的输出与请求的“伦敦和德国”不匹配

现代 Python 可以直接处理 IP 地址:

#! /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))

这会打印找到的位置,并and在最后找到的两个位置之间放置“”,,在所有其他位置之间放置“”(如果适用):例如London, Paris and Germany

假设数据位于名为 的文件中input,使脚本可执行,或使用python scriptname 172.25.2.32

答案2

在这种情况下,使用通常可用于 Unix 和 Linux 系统的多种通用编程语言之一(作为默认安装的一部分或通过简单的软件包安装)可能是最简单的。以下是如何使用 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

这并不是特别好的Ruby,但它能够利用该ipaddr库来避免手动解析 IP 地址。虽然在示例文本中手动处理并不是什么大问题,但当您具有 172.25.2.0-172.25.3.200 等范围时,手动处理会更加困难。

您的问题被标记为bashtext-processing。如果您正在使用更广泛使用的文本处理工具(例如 sed、awk 和 grep)寻找答案,那么您可能只想查看上面 ruby​​ 脚本中包含的一般策略:

  1. 将 IP 地址参数存储在变量中以便稍后访问
  2. 读取文件的每一行
  3. 确定该行是位置描述还是 IP 地址范围。
  4. 如果是位置描述,则存放在last_location中
  5. 如果是 IP 地址范围,请确定您的 IP 是否在该范围内
  6. 如果 ip 在范围内,则打印出 last_location 变量。

它不是最优雅的解决方案,但它是一种可以直接用多种语言实现的解决方案,并且熟悉该语言的任何人都可以轻松遵循。

答案3

perl的版本史蒂文的回答:

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...

相关内容