从 VBoxManage 输出解析以冒号分隔的表格数据
Parsing colon delimited tabular data from VBoxManage output
我正在编写一些包装 VirtualBox 的 ansible 剧本 VBoxManage cli。返回的数据采用冒号分隔的表格格式,但我希望它采用类似 JSON/YAML 的格式以便更好地解析。
例如,我想获取以下命令的输出:
$ VBoxManage list hostonlyifs -l
Name: VirtualBox Host-Only Ethernet Adapter #2
GUID: 355aa3ae-0a32-49e6-8532-4d18fd9baea2
DHCP: Disabled
IPAddress: 10.0.10.10
NetworkMask: 255.255.255.0
IPV6Address: fe80::acc9:a7bd:d178:b911
IPV6NetworkMaskPrefixLength: 64
HardwareAddress: 0a:00:27:00:00:3b
MediumType: Ethernet
Wireless: No
Status: Up
VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter #2
Name: VirtualBox Host-Only Ethernet Adapter
GUID: 405a4779-a6f3-47d9-bf83-6a2503a093f2
DHCP: Disabled
IPAddress: 192.168.56.1
NetworkMask: 255.255.255.0
IPV6Address: fe80::ede5:3927:714c:3958
IPV6NetworkMaskPrefixLength: 64
HardwareAddress: 0a:00:27:00:00:06
MediumType: Ethernet
Wireless: No
Status: Up
VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter
并引用 HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter #2
接口的 IP 地址。
接近我正在寻找的示例 ansible 任务:
#!/usr/bin/env ansible-playbook
- hosts: localhost
become: false
gather_facts: false
vars_files:
- vars/main.yml
tasks:
- name: List all host-only interfaces
shell: "VBoxManage list hostonlyifs
| <magic>"
changed_when: false
register: vbox_hostonlyifs
- name: Use information from the previous command somehow
shell: "VBoxManage hostonlyif ipconfig
'{{ vbox_hostonlyifs.stdout | <magic> }}'
--ip 10.0.10.0"
我在想 sed/regex 的组合也许可以解决问题。
我有一个正则表达式,可以从所有块中捕获键和值,而不是块本身。
(^[a-zA-Z0-9]+:)(?:[ \t]+)(.*)$
你可以利用输出是 almost yaml 的事实,稍微修改一下就可以把它变成一个列表:
tasks:
- shell: VBoxManage list hostonlyifs | sed -e 's/^/ /; s/^ Name:/- Name:/'
register: vblist
- set_fact:
vbox_interfaces: '{{ vblist.stdout | from_yaml }}'
通过在 Name:
键前加上 - Name:
将它们变成列表项,然后唯一的其他要求是缩进其余键以匹配与 [= 相同的缩进13=] 将它们变成对象
我有充分的理由相信你可以使用纯 jinja2 而不是使用 sed =]
运行 本地生产:
ok: [localhost] => {
"vbox_interfaces": [
{
"DHCP": "Disabled",
"GUID": "786f6276-656e-4074-8000-0a0027000000",
"HardwareAddress": "0a:00:27:00:00:00",
"Status": "Down",
...etc etc
"VBoxNetworkName": "HostInterfaceNetworking-vboxnet0",
"Wireless": false
},
{
"DHCP": "Disabled",
"GUID": "786f6276-656e-4374-8000-0a0027000003",
"HardwareAddress": "0a:00:27:00:00:03",
...etc etc
}
]
}
相同,但对于 Windows(我的 extpack 示例):
- name: Get facts about Extension Pack 4 Windows
when:
- ansible_os_family == 'Windows'
become: yes
become_method: runas
become_flags: logon_type=new_credentials logon_flags=netcredentials_only
win_shell: |
$for_yaml = VBoxManage list extpacks
$for_yaml -replace '^', ' ' -replace ' Extension', '- Extension'
register: vboxmanage_list_extpacks_windows
- set_fact:
virtualbox_installed_extpack_info_fact:
"{{ vboxmanage_list_extpacks_windows.stdout
| from_yaml
| first }}"
结果:
{
"virtualbox_installed_extpack_info_fact": {
"Description": "Oracle Cloud Infrastructure integration, USB 2.0 and USB 3.0 Host Controller, Host Webcam, VirtualBox RDP, PXE ROM, Disk Encryption, NVMe.",
"Edition": null,
"Extension Packs": 1,
"Pack no. 0": "Oracle VM VirtualBox Extension Pack",
"Revision": 149290,
"Usable": true,
"VRDE Module": "VBoxVRDP",
"Version": "6.1.32",
"Why unusable": null
}
}
我正在编写一些包装 VirtualBox 的 ansible 剧本 VBoxManage cli。返回的数据采用冒号分隔的表格格式,但我希望它采用类似 JSON/YAML 的格式以便更好地解析。
例如,我想获取以下命令的输出:
$ VBoxManage list hostonlyifs -l
Name: VirtualBox Host-Only Ethernet Adapter #2
GUID: 355aa3ae-0a32-49e6-8532-4d18fd9baea2
DHCP: Disabled
IPAddress: 10.0.10.10
NetworkMask: 255.255.255.0
IPV6Address: fe80::acc9:a7bd:d178:b911
IPV6NetworkMaskPrefixLength: 64
HardwareAddress: 0a:00:27:00:00:3b
MediumType: Ethernet
Wireless: No
Status: Up
VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter #2
Name: VirtualBox Host-Only Ethernet Adapter
GUID: 405a4779-a6f3-47d9-bf83-6a2503a093f2
DHCP: Disabled
IPAddress: 192.168.56.1
NetworkMask: 255.255.255.0
IPV6Address: fe80::ede5:3927:714c:3958
IPV6NetworkMaskPrefixLength: 64
HardwareAddress: 0a:00:27:00:00:06
MediumType: Ethernet
Wireless: No
Status: Up
VBoxNetworkName: HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter
并引用 HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter #2
接口的 IP 地址。
接近我正在寻找的示例 ansible 任务:
#!/usr/bin/env ansible-playbook
- hosts: localhost
become: false
gather_facts: false
vars_files:
- vars/main.yml
tasks:
- name: List all host-only interfaces
shell: "VBoxManage list hostonlyifs
| <magic>"
changed_when: false
register: vbox_hostonlyifs
- name: Use information from the previous command somehow
shell: "VBoxManage hostonlyif ipconfig
'{{ vbox_hostonlyifs.stdout | <magic> }}'
--ip 10.0.10.0"
我在想 sed/regex 的组合也许可以解决问题。
我有一个正则表达式,可以从所有块中捕获键和值,而不是块本身。
(^[a-zA-Z0-9]+:)(?:[ \t]+)(.*)$
你可以利用输出是 almost yaml 的事实,稍微修改一下就可以把它变成一个列表:
tasks:
- shell: VBoxManage list hostonlyifs | sed -e 's/^/ /; s/^ Name:/- Name:/'
register: vblist
- set_fact:
vbox_interfaces: '{{ vblist.stdout | from_yaml }}'
通过在 Name:
键前加上 - Name:
将它们变成列表项,然后唯一的其他要求是缩进其余键以匹配与 [= 相同的缩进13=] 将它们变成对象
我有充分的理由相信你可以使用纯 jinja2 而不是使用 sed =]
运行 本地生产:
ok: [localhost] => {
"vbox_interfaces": [
{
"DHCP": "Disabled",
"GUID": "786f6276-656e-4074-8000-0a0027000000",
"HardwareAddress": "0a:00:27:00:00:00",
"Status": "Down",
...etc etc
"VBoxNetworkName": "HostInterfaceNetworking-vboxnet0",
"Wireless": false
},
{
"DHCP": "Disabled",
"GUID": "786f6276-656e-4374-8000-0a0027000003",
"HardwareAddress": "0a:00:27:00:00:03",
...etc etc
}
]
}
相同,但对于 Windows(我的 extpack 示例):
- name: Get facts about Extension Pack 4 Windows
when:
- ansible_os_family == 'Windows'
become: yes
become_method: runas
become_flags: logon_type=new_credentials logon_flags=netcredentials_only
win_shell: |
$for_yaml = VBoxManage list extpacks
$for_yaml -replace '^', ' ' -replace ' Extension', '- Extension'
register: vboxmanage_list_extpacks_windows
- set_fact:
virtualbox_installed_extpack_info_fact:
"{{ vboxmanage_list_extpacks_windows.stdout
| from_yaml
| first }}"
结果:
{
"virtualbox_installed_extpack_info_fact": {
"Description": "Oracle Cloud Infrastructure integration, USB 2.0 and USB 3.0 Host Controller, Host Webcam, VirtualBox RDP, PXE ROM, Disk Encryption, NVMe.",
"Edition": null,
"Extension Packs": 1,
"Pack no. 0": "Oracle VM VirtualBox Extension Pack",
"Revision": 149290,
"Usable": true,
"VRDE Module": "VBoxVRDP",
"Version": "6.1.32",
"Why unusable": null
}
}