Python 将命令输出表转换为字典
我正在脚本中运行Python 将命令输出表转换为字典,python,python-3.x,dictionary,subprocess,Python,Python 3.x,Dictionary,Subprocess,我正在脚本中运行'arp-scan-l'命令。当前我的代码返回以下字符串变量结果: 192.168.200.190:ef:68:f8:8b:c2 ZyXEL通信公司 192.168.200.81 60:45:cb:6c:5e:3e(未知) 192.168.200.83 0c:fe:45:4b:b8:98索尼互动娱乐公司。 192.168.200.106 ac:84:c6:57:f7:19 TP链路 192.168.200.72 50:dc:e7:67:bd:e0(未知) 192.168.200.
'arp-scan-l'
命令。当前我的代码返回以下字符串变量结果:
192.168.200.190:ef:68:f8:8b:c2 ZyXEL通信公司
192.168.200.81 60:45:cb:6c:5e:3e(未知)
192.168.200.83 0c:fe:45:4b:b8:98索尼互动娱乐公司。
192.168.200.106 ac:84:c6:57:f7:19 TP链路
192.168.200.72 50:dc:e7:67:bd:e0(未知)
192.168.200.157 5c:52:1e:59:2c:d1 TP链路
192.168.200.229 f8:62:14:5a:9e:c7(未知)
如果我只是拆分这个输出,它会创建一个如下列表:('ip\mac\sony interactive entertainment')
我希望输出为:('ip','mac','sony interactive entertainment')
到目前为止,我的代码是:
arp_cmd = ['arp-scan', '-l']
run_command = subprocess.Popen(arp_cmd, stdout=subprocess.PIPE)
output_bytes = run_command.communicate()[0]
output_str = output_bytes.decode("utf-8")
print(output_str.split('/n'))
输出:
[192.168.200.1\t90:ef:68:f8:8b:c2\tZyXEL通信公司\n192.168.200.81\t60:45:cb:6c:5e:3e\t(未知)\n192.168.200.81\t60:45:cb:6c:5e:3e\t(未知)(DUP:2)\n192.168.200.83\t0c:fe:45:4b:b8\tSony互动娱乐公司。\n192.168.200.83\t0c:fe:45:4b互动娱乐公司\n192.168.200.106\tac:84:c6:57:f7:19\t(未知)\n192.168.200.72\t50:dc:e7:67:bd:e0\t(未知)\n192.168.200.150\t5c:f9:38:d1:25:b5\tApple,Inc.\n192.168.200.150\t5c:f9:38:d1:25:b5\tApple,Inc.(DUP:2)\n192.168.200.157\t5c:52:1e:59:2c:d1\t(未知)\n192.168.168.15\t5c:52:19\t\n192.168.150\t5c:58\t(未知)通用代码
通常,split
有一个关键字maxslit
,您可以在其中指定要进行的最大拆分次数。例如
>>> s = 'IP MAC Sony Interactive Entertainment'
>>> s.split(' ', maxsplit=2)
['IP', 'MAC', 'Sony Interactive Entertainment']
它将按您在maxslit
中指定的次数拆分字符串,剩余部分将转换为单个字符串
评论
输出是一个包含一个字符串的列表;其中,arp
命令中的每一行都是换行分隔的
output = ['192.168.200.1\t90:ef:68:f8:8b:c2\tZyXEL Communications Corporation\n192.168.200.81\t60:45:cb:6c:5e:3e\t(Unknown)\n192.168.200.83\t0c:fe:45:4b:b8:98\tSony Interactive Entertainment Inc.\n192.168.200.83\t0c:fe:45:4b:b8:98\tSony Interactive Entertainment Inc. (DUP: 2)\n192.168.200.106\tac:84:c6:57:f7:19\t(Unknown)\n192.168.200.72\t50:dc:e7:67:bd:e0\t(Unknown)\n192.168.200.150\t5c:f9:38:d1:25:b5\tApple, Inc.\n192.168.200.150\t5c:f9:38:d1:25:b5\tApple, Inc. (DUP: 2)\n192.168.200.157\t5c:52:1e:59:2c:d1\t(Unknown)\n192.168.200.229\tf8:62:14:5a:9e:c7\t(Unknown)']
将单个字符串拆分为一个列表
,其中包含来自arp
命令的每一行,作为一个单独的字符串
>>> item_list = output[0].split('\n')
>>> item_list
['192.168.200.1\t90:ef:68:f8:8b:c2\tZyXEL Communications Corporation',
'192.168.200.81\t60:45:cb:6c:5e:3e\t(Unknown)',
....]
现在,每一行都是简单地分开的,因此不需要使用maxsplit。以第一项为例:
>>> item_one = item_list[0]
>>> item_one.split('\t')
['192.168.200.1', '90:ef:68:f8:8b:c2', 'ZyXEL Communications Corporation']
考虑到这一点,您可以迭代完整的项目列表
,以生成列表列表:
>>> output_list = list()
>>> for item in item_list:
... output.append(item.split('\t'))
...
>>> output_list
[['192.168.200.1', '90:ef:68:f8:8b:c2', 'ZyXEL Communications Corporation'],
['192.168.200.81', '60:45:cb:6c:5e:3e', '(Unknown)'],
....]]
挤成一行
解决方案
我能做到这一点的另一种方法是:
重新导入
s=”“”
192.168.200.1 90:ef:68:f8:8b:c2 ZyXEL通信公司
192.168.200.81 60:45:cb:6c:5e:3e(未知)
192.168.200.83 0c:fe:45:4b:b8:98索尼互动娱乐公司。
192.168.200.106 ac:84:c6:57:f7:19 TP链路
192.168.200.72 50:dc:e7:67:bd:e0(未知)
192.168.200.157 5c:52:1e:59:2c:d1 TP链路
192.168.200.229 f8:62:14:5a:9e:c7(未知)
"""
found=re.findall(r“(\S+)\S+(\S+)\S+(.*)\n?”,S)
打印(已找到)
##印刷品:
##[('192.168.200.1','90:ef:68:f8:8b:c2','ZyXEL Communications Corporation'),('192.168.200.81','60:45:cb:6c:5e:3e','(未知),('192.168.200.83','0c:fe:45:4b:b8:98','Sony Interactive Entertainment Inc.),('192.168.200.106','ac:84:c6:57:f7:19','TP-LINK',('192.168.200.72','50:dc:e7:e0','(未知),('192.168.200.157','5c:52:1e:59:2c:d1','TP链接'),('192.168.200.229','f8:62:14:5a:9e:c7','(未知)]
解释
模式=(\S+)\S+(\S+)\S+(.*)\n?
此解决方案使用正则表达式查找正确的字符串。在这种情况下:由空格字符分隔的非空格字符,并可选地以换行结束
Findall以元组列表的形式返回结果(因为我们指定了多个组)在mac和name之间可能有两个选项卡可以使用?我刚才正在运行s.split('/n'))
。如果列表中有大约10个项目,maxsplit可以工作吗?它看起来适用于第一行,并将表的其余部分变成一个值。您能否提供整个“输出”\u str值,arp
命令中的每一行的分隔符是什么,以及您要查找的整个输出(而不是一行)?然后我应该能够为您提供完整的解决方案。现在我将它作为子进程命令运行,因此它正在扫描我的家庭网络。我使用上面的帖子当前输出内容编辑帖子当我运行它时,它在终端中。它几乎显示了一个带有IP、MAC的表,然后是标签的名称。它会在新的一行中为找到的每个设备重复。谢谢!谢谢-你能用你自己的split命令提供完整的输出吗?它只是把东西混合在一起[192.168.200.1\t90:ef:68:f8:8b:c2\tZyXEL Communications Corporation\n192.168.200.81\t60:45:cb:6c:5e:3e\t(未知)\n192.168.200.83\t0c:fe:45:4b:b8\tSony Interactive Entertainment Inc.\n192.168.200.106\tSony Interactive Entertainment Inc.(DUP:2)\n192.168.200.106\tac:84:c6:57\tSony Interactive Entertainment Inc.(未知)\n192.168.200.72\t50:dc:e7:67:bd:e0\t(未知)\n192.168.200.150\t5c:f9:38:d1:25:b5\tApple,Inc.\n192.168.200.157\t5c:52:1e:59:2c:d1\t(未知)\n192.168.200.229\tf8:62:14:5a:9e:c7\t(未知)]
>>> [item.split('\t') for item in output[0].split('\n')]