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