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

时间:2015-11-17 19:36:27

标签: python mac-address

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

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

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

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

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地址是否在网络上,是否打印出来?

4 个答案:

答案 0 :(得分:2)

从你拥有的东西开始:

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)

答案 1 :(得分:1)

要获取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]事件。

答案 2 :(得分:0)

在每个项目中使用分割()计数 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

输出:

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

您也可以使用列表推导(listcomps):

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

输出:

ROOT_MACRO(x,y)

答案 3 :(得分:0)

您可以解析/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)