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')]