我正在尝试使用bash从头开始创建JSON。
最终结构必须如下:
{
"hosts": {
"a_hostname" : {
"ips" : [
1,
2,
3
]
},
{...}
}
}
首先,我创建一个格式为
的输入文件hostname ["1.1.1.1","2.2.2.2"]
host-name2 ["3.3.3.3","4.4.4.4"]
这是由以下人员创建的:
for host in $( ansible -i hosts all --list-hosts ) ; \
do echo -n "${host} " ; \
ansible -i hosts $host -m setup | sed '1c {' | jq -r -c '.ansible_facts.ansible_all_ipv4_addresses' ; \
done > hosts.txt
这里的关键点是IP列表/数组来自JSON文件并由jq提取。此提取输出已经有效/引用的JSON数组,但是作为txt文件中的字符串。
接下来我使用jq将整个文本文件解析为所需的JSON:
jq -Rn '
{ "hosts": [inputs |
split("\\s+"; "g") |
select(length > 0 and .[0] != "") |
{(.[0]):
{ips:.[1]}
}
] | add }
' < ~/hosts.txt
这几乎是正确的,除了被视为字符串并引用的IP值之外的所有内容都导致:
{
"hosts": {
"hostname1": {
"ips": "[\"1.1.1.1\",\"2.2.2.2\"]"
},
"host-name2": {
"ips": "[\"3.3.3.3\",\"4.4.4.4\"]"
}
}
}
我现在陷入了最后的障碍 - 如何插入IP而不会再引用它们。
修改 - 使用{ips: .[1] | fromjson }}
代替{ips:.[1]}
解决引用问题。
然而,@ CharlesDuffy的帮助suggesting converting to TSV完全否定了这一点。
到目前为止,我已经
了jq -n {hosts:{}} | \
for host in $( ansible -i hosts all --list-hosts ) ; \
do jq ".hosts += {$host:{}}" | \
jq ".hosts.$host += {ips:[1,2,3]}" ; \
done ;
([1,2,3]
实际上是来自一个子shell,但包含它似乎是不必要的,因为该部分有效,并使其更难阅读)
这种作品,但似乎有两个问题。
1)最终输出中只有一个主机,其中包含列表中第一个主机的数据(即使第二个问题被绕过,这仍然存在):
{
"hosts": {
"host_1": {
"ips": [
1,
2,
3
]
}
}
}
2)其中一个主机名中有-
,导致jq出现语法错误和编译错误。我一直坚持报价地狱试图让它被解释,但也被引用。救命啊!
感谢您的任何意见。
答案 0 :(得分:3)
假设您的输入格式为:
host_1 1 2 3
host_2 2 3 4
host-with-dashes 3 4 5
host-with-no-addresses
... re:编辑指定不同的格式:将@tsv
添加到JQ命令中,生成现有格式以生成此格式。
如果您想将其转换为相关格式,则可能如下所示:
jq -Rn '
{ "hosts": [inputs |
split("\\s+"; "g") |
select(length > 0 and .[0] != "") |
{(.[0]): .[1:]}
] | add
}' <input.txt
作为输出产生的结果:
{
"hosts": {
"host_1": [
"1",
"2",
"3"
],
"host_2": [
"2",
"3",
"4"
],
"host-with-dashes": [
"3",
"4",
"5"
],
"host-with-no-addresses": []
}
}