json - 从 VBoxManage 输出中解析冒号分隔的表格数据

标签 json bash data-structures ansible virtualbox

我正在编写一些包装 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 接口(interface)的 IP 地址。

一个接近我正在寻找的任务的示例:

#!/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 的组合可以解决这个问题。

我有一个正则表达式,它将捕获所有 block 中的键和值,但不捕获 block 本身。

(^[a-zA-Z0-9]+:)(?:[\t]+)(.*)$

最佳答案

您可以利用输出几乎 yaml这一事实,只需稍加修改即可将其转换为列表:

tasks:
- shell: VBoxManage list hostonlyifs | sed -e 's/^/  /; s/^  Name:/- Name:/'
  register: vblist
- set_fact:
    vbox_interfaces: '{{ vblist.stdout | from_yaml }}'

通过在 Name: 键前加上 - Name: 前缀,它将它们转换为列表项,然后唯一的其他要求是缩进其余键以匹配与 - Name: 相同的缩进使它们成为对象

我有充分的理由相信你可以使用纯 jinja2 来做到这一点,而不是使用 sed,但既然你已经提到了 sed,看来你可以使用 ansible 和 shell 的混合物

在本地运行会产生:

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
        }
    ]
}

关于json - 从 VBoxManage 输出中解析冒号分隔的表格数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57837867/

相关文章:

最小最大堆的Java实现?

json - Golang 将 2 个 JSON 项解码为 1 个结构

php - JSON 编码 - 获取 MySQL 数据到 iPhone

php - 存储网站数据 - JSON 与 SQL

bash - imagemagick 转换 : how to tell if images need to be rotated?

java - 在 HashMap 中将 float[] 转换为 double[]

c# - 数组中等于 N 的 K 个元素之和

php - 是否可以在 Laravel 查询生成器中按条件将自定义字段添加到 JSON?

linux - 使用多个 Linux 隧道运行 Windows 脚本

bash - 如何总结 BASH 中所有源代码的行数?