【问题标题】:How to sort IP addresses with port number?如何使用端口号对 IP 地址进行排序?
【发布时间】:2019-08-07 09:50:41
【问题描述】:

我正在创建自己的报告工具,并试图弄清楚如何使用端口号对 IP 地址进行排序。

如何使用端口号对 IP 地址进行排序,以便我先对 IP 地址进行排序,然后再通过端口号进行排序。我可以很好地对 IP 地址进行排序,但是当与端口号结合时,它变得很困难。

a = ['192.168.0.3 (443/tcp)|', '192.168.0.176 (443/tcp)|', '192.168.0.40 (443/tcp)|', '192.168.0.15 (8443/tcp)|', '192.168.0.16 (8443/tcp)|', '192.168.0.12 (443/tcp)|', '192.168.0.9 (3389/tcp)|', '192.168.0.15 (443/tcp)|', '192.168.0.16 (443/tcp)|', '192.168.0.3 (3389/tcp)|', '192.168.0.14 (443/tcp)|']

print(a.sort(key=lambda s: map(int, s.split('.')))) #this works fine with just IP address not with the current format of (xxx/tcp). The pipe is for delimiters so please ignore.

我想首先按 IP 地址排序输出,然后为每个 IP 按端口号排序。例如,前几个结果将是:

a= ['192.168.0.3 (443/tcp)|', '192.168.0.3 (3389/tcp)|', 192.168.0.9 (3389/tcp)|, ...']

【问题讨论】:

  • 不应该'192.168.0.9 (3389/tcp)|' 是所需输出中的第三个吗?
  • @Chris 已更正,谢谢

标签: python sorting ip


【解决方案1】:

使用re.findall:

import re

def get_ip_port(x):
    *ips, port = map(int, re.findall('\d+', x))
    return ips, port

sorted(a, key=get_ip_port)

输出:

['192.168.0.3 (443/tcp)|',
 '192.168.0.3 (3389/tcp)|',
 '192.168.0.9 (3389/tcp)|',
 '192.168.0.12 (443/tcp)|',
 '192.168.0.14 (443/tcp)|',
 '192.168.0.15 (443/tcp)|',
 '192.168.0.15 (8443/tcp)|',
 '192.168.0.16 (443/tcp)|',
 '192.168.0.16 (8443/tcp)|',
 '192.168.0.40 (443/tcp)|',
 '192.168.0.176 (443/tcp)|']

解释:

  • map(int, re.findall('\d+', x)):查找所有数字并将它们设为int
  • *ips, port:解压上面的ints 并重新打包到除了最后一个 (*ips) 和最后一个 (port) 之外的所有内容
  • sorted(a, key=get_ip_port): 因为get_ip_port 返回两个键(ips,port),sorteda 首先按ips 排序,然后按port 排序。

【讨论】:

  • 这很好,你能解释/评论一下这些步骤的作用吗?谢谢。
  • @Anderson 已更新。如果有任何不清楚的地方,请告诉我。
【解决方案2】:

您可以使用多个条件进行排序(map(int,e[0].split('.'))作为条件1,int(e[1].lstrip('(').split('/')[0])作为条件2)如下所示,

>>> a
['192.168.0.3 (443/tcp)|',
 '192.168.0.176 (443/tcp)|',
 '192.168.0.40 (443/tcp)|',
 '192.168.0.15 (8443/tcp)|',
 '192.168.0.16 (8443/tcp)|',
 '192.168.0.12 (443/tcp)|',
 '192.168.0.9 (3389/tcp)|',
 '192.168.0.15 (443/tcp)|',
 '192.168.0.16 (443/tcp)|',
 '192.168.0.3 (3389/tcp)|',
 '192.168.0.14 (443/tcp)|']
>>> [i.split() for i in a]
[['192.168.0.3', '(443/tcp)|'],
 ['192.168.0.176', '(443/tcp)|'],
 ['192.168.0.40', '(443/tcp)|'],
 ['192.168.0.15', '(8443/tcp)|'],
 ['192.168.0.16', '(8443/tcp)|'],
 ['192.168.0.12', '(443/tcp)|'],
 ['192.168.0.9', '(3389/tcp)|'],
 ['192.168.0.15', '(443/tcp)|'],
 ['192.168.0.16', '(443/tcp)|'],
 ['192.168.0.3', '(3389/tcp)|'],
 ['192.168.0.14', '(443/tcp)|']]

>>> sorted([i.split() for i in a],key=lambda e: (map(int,e[0].split('.')),int(e[1].strip('(').split('/')[0])))
[['192.168.0.3', '(443/tcp)|'],
 ['192.168.0.3', '(3389/tcp)|'],
 ['192.168.0.9', '(3389/tcp)|'],
 ['192.168.0.12', '(443/tcp)|'],
 ['192.168.0.14', '(443/tcp)|'],
 ['192.168.0.15', '(443/tcp)|'],
 ['192.168.0.15', '(8443/tcp)|'],
 ['192.168.0.16', '(443/tcp)|'],
 ['192.168.0.16', '(8443/tcp)|'],
 ['192.168.0.40', '(443/tcp)|'],
 ['192.168.0.176', '(443/tcp)|']]

【讨论】:

    【解决方案3】:

    您可以像这样使用sorted 在一行中完成:

    sorted(a, key=lambda x:x.split(' ')[0])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-25
      • 2011-09-09
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 2011-10-02
      • 2016-03-04
      • 1970-01-01
      相关资源
      最近更新 更多