Python 获取 mac 个地址的列表并将它们与文件中的列表进行比较

Python get list of mac addresses and compare them with list from file

我是Python的初学者,希望您能帮我解决这个问题。

我有一份 mac 地址列表,写在一个文件中。我需要获取网络上的 mac 地址列表,将它们与文件中的地址进行比较,然后在标准输出中打印在网络地址列表中未找到的文件中的地址。

最后用这些地址更新文件。

现在我设法读取了一个我作为参数提供的文件:

import sys

with open(sys.argv[1], 'r') as my_file:
   lines = my_file.read()

my_list = lines.splitlines()

我正在尝试通过 运行 来自 python:

的进程 arp 来读取 mac 地址
import subprocess

addresses = subprocess.check_output(['arp', '-a'])

但是使用这段代码我得到了这个:

  Internet Address      Physical Address      Type
  156.178.1.1           5h-c9-6f-78-g9-91     dynamic
  156.178.1.255         ff-ff-ff-ff-ff-ff     static
  167.0.0.11            05-00-9b-00-00-10     static
  167.0.0.123           05-00-9b-00-00-ad     static
  .....

如何在此处进行过滤以便仅获取 mac 个地址的列表?

或者我可以像这样检查两个列表以查看文件中的 mac 地址是否在网络上,如果不在则将其打印出来?

使用split()计算-个字符的数量在每个项目中:

text = """  Internet Address      Physical Address      Type
  156.178.1.1           5h-c9-6f-78-g9-91     dynamic
  156.178.1.255         ff-ff-ff-ff-ff-ff     static
  167.0.0.11            05-00-9b-00-00-10     static
  167.0.0.123           05-00-9b-00-00-ad     static
  ....."""

for item in text.split():
    if item.count('-') == 5:
        print item

输出:

5h-c9-6f-78-g9-91
ff-ff-ff-ff-ff-ff
05-00-9b-00-00-10
05-00-9b-00-00-ad

您也可以使用 list comprehensions (listcomps):

print [item for item in text.split() if item.count('-') == 5]

输出:

['5h-c9-6f-78-g9-91', 'ff-ff-ff-ff-ff-ff', '05-00-9b-00-00-10', '05-00-9b-00-00-ad']

从你拥有的开始:

networkAdds = addresses.splitlines()[1:]
networkAdds = set(add.split(None,2)[1] for add in networkAdds if add.strip())
with open(sys.argv[1]) as infile: knownAdds = set(line.strip() for line in infile)

print("These addresses were in the file, but not on the network")
for add in knownAdds - networkAdds:
    print(add)

您可以解析 /proc/net/arp 并完全避免需要子进程:

with open("/proc/net/arp") as f, open(sys.argv[1], 'r') as my_file:
    next(f)
    mac_addrs = {mac for  _, _, _, mac,_, _ in map(str.split, f)}
    for mac in map(str.rstrip, my_file):
        if mac not in mac_addrs:
           print("No entry for addr: {}".format(mac))

/proc/net/arp 看起来像:

IP address       HW type     Flags       HW address            Mask     Device
xxx.xxx.xxx.xxx    0x1         0x2         xx:xx:xx:xx:xx:xx     *        wlan0

其中第四列是 mac/hw 地址。如果你使用 arp,你可能还会发现 arp -an 给你更少的输出来解析。

如果您想添加网络中列出但文件中没有的 mac,您可以使用 "a+" 打开并在文件末尾附加任何未看到的值:

with open("/proc/net/arp") as f, open(sys.argv[1], 'a+') as my_file:
        next(f)
        mac_addrs = {mac for _, _, _, mac,_, _ in map(str.split, f)}
        for mac in map(str.rstrip, my_file):
            if mac not in mac_addrs:
               print("No entry for addr: {}".format(mac))
            else:
                mac_addrs.remove(mac)
        my_file.writelines("{}\n".format(mac)for mac in mac_addrs)

要获取 MAC 地址,您可以使用此正则表达式:

import re

addresses = """  Internet Address      Physical Address      Type
156.178.1.1           5f-c9-6f-78-f9-91     dynamic
156.178.1.255         ff-ff-ff-ff-ff-ff     static
167.0.0.11            05-00-9b-00-00-10     static
167.0.0.123           05-00-9b-00-00-ad     static
....."""

print(re.findall(('(?:[0-9a-fA-F]{1,}(?:\-|\:)){5}[0-9a-fA-F]{1,}'),addresses))

输出:

['5f-c9-6f-78-f9-91', 'ff-ff-ff-ff-ff-ff', '05-00-9b-00-00-10', '05-00-9b-00-00-ad']

据我所知,您的 MAC-地址不遵循此正则表达式中使用的命名约定,因此您可以使用 [0-9a-fA-F] 东西。