【问题标题】:How do I get ip address and mac address from arp output via Python regex?如何通过 Python 正则表达式从 arp 输出中获取 ip 地址和 mac 地址?
【发布时间】:2018-07-09 06:55:55
【问题描述】:

我想从 Ubuntu 上的 arp 命令行输出中获取 mac 地址和相应的 ip 地址(例如,作为以 mac 地址作为键和 ip 地址的字典)作为值。

$ arp
Address                  HWtype  HWaddress           Flags Mask            Iface
XX.X.X.X(XX)                ether   XX:XX:XX:XX:XX:XX   C                     eth0
<host name>                 ether   XX:XX:XX:XX:XX:XX   C                     eth0

ip 地址(?P&lt;ip&gt;\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) 的正则表达式和mac 的正则表达式(?P&lt;mac&gt;[0-9a-f]{2}[:]){5}([0-9a-f]{2}) 各自工作正常。如何将这两者结合起来并忽略 ip 地址和 mac 之间的所有内容?如何改进 ip 地址正则表达式以匹配主机名?如果有更好的替代方法来使用arp 来获取ip 地址和macs,我很乐意改用这个命令。

【问题讨论】:

  • 将文本拆分为行,将行拆分为字段可能会比正则表达式提供更好的结果。

标签: python arp


【解决方案1】:

为了加入它们而忽略中间信息,只需在中间添加“.*”,这样它就可以匹配任何东西,但不会被分配到一个组:

(?P<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*([0-9a-f]{2}[:]){5}([0-9a-f]{2})

为了考虑主机名,捕获第一个字段可能会更好,而不是尝试确保它是正确的 IP 或主机名。只需捕获第一个字段,直到空格:

^(?P<ip>[^\s]+)

所以第一个有洞的字段和 MAC 最终是:

^(?P<ip>[^\s]+).*(?P<mac>(?:[0-9a-f]{2}:){5}[0-9a-f]{2})

【讨论】:

  • 当我在regex101.com 上调试正则表达式时,您的第一个建议确实匹配了组 ip(ip 以及主机名),但没有正确匹配 mac。您对 mach 组的第二个建议添加了 ^(?P&lt;ip&gt;[^\s]+).*(?P&lt;mac&gt;[0-9a-f]{2}[:]){5}([0-9a-f]{2}) 正确匹配的组 ip(ip 以及主机名),但对于 mac 也没有。
  • 好吧,我相信您告诉我们您的 mac 正则表达式可以正常工作以满足您的需求。如果不是这样......不要怪我:P你只需要把括号放在正确的位置:^(?P&lt;ip&gt;[^\s]+).*(?P&lt;mac&gt;([0-9a-f]{2}:){5}[0-9a-f]{2})
  • 如果我只使用了 mac 正则表达式,它确实有效???无论如何,非常感谢。请按评论修复答案...
【解决方案2】:

我建议通过减少文本解析的开销来从 shell 本身和那里按列提取。

a = subprocess.check_output(["arp | awk '{print $1,$3}'"], shell = True)

# Ip address
for i in a.split('\n')[:-1]:
    print(i.split()[0])

# Mac address
for i in a.split('\n')[:-1]:
    print(i.split()[1])

【讨论】:

  • 这个命令行表达式用subprocess.check_output(...)之类的调用有点笨拙...
  • 我相信当您实际尝试使用正则表达式进行解析时,它确实可以为您节省大量开销
  • 好的。这只是一个建议。我也添加了子进程调用。
【解决方案3】:

也可以使用 Python scapy 模块来获取 mac

from scapy.all import *
def get_mac(ip_address):
    responses,unanswered = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=ip_address),timeout=2,retry=10)
# return the MAC address from a response
    for s,r in responses:
        return r[Ether].src
    return None

print(get_mac("192.168.31.14"))

【讨论】:

    猜你喜欢
    • 2017-03-15
    • 2015-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-10
    • 2022-10-04
    • 1970-01-01
    相关资源
    最近更新 更多