我有一个看起来像这样的json变量:
{
"status": "closed",
"host": "host1-availabe_zone_A"
}
{
"status": "closed",
"host": "host2-availabe_zone_B"
}
{
"status": "closed",
"host": "host3-availabe_zone_A"
}
我正在尝试将其转换为类似哈希的数据结构(zsh / bash中的关联数组),以获取每个可用区中的主机数。根据上面的数据,首选结果将是这样:
availabe_zone_A -> 2
availabe_zone_B -> 1
尝试迭代json变量时遇到一些问题。
declare -A az_to_number_of_open_hosts
for host in $(jq . <<< $hosts_list)
do
az=$(rev <<< $(echo $host | jq .host) | cut -d. -f3 | rev)
((az_to_number_of_open_hosts[$az]++))
done
提取可用区域的行是因为主机格式始终为blabla123213.az.domain.com
。
该代码不起作用,因为似乎变量host
指向json字符串的每一行,而不是json条目。有没有推荐的方法来迭代每个json条目?
答案 0 :(得分:1)
您只是在计算json中的值。分割出您要计数的部分
template<class T>
struct CanDoX<T, std::void_t<decltype(x(std::declval<const T&>()))>>:std::true_type{};
然后您可以分组并计数:
$ jq -nr 'inputs.host/"-"|last' input.json
availabe_zone_A
availabe_zone_B
availabe_zone_A
https://jqplay.org/s/g_8HgqiQ1o
或遍历迭代的值:
$ jq -nr '[inputs.host/"-"|last]|group_by(.)[]|"\(.[0]) -> \(length)"' input.json
availabe_zone_A -> 2
availabe_zone_B -> 1
答案 1 :(得分:0)
使用.host
获取host
属性。
$ hosts_list=' {
"status": "closed",
"host": "host1-availabe_zone_A"
}
{
"status": "closed",
"host": "host2-availabe_zone_B"
}
{
"status": "closed",
"host": "host3-availabe_zone_A"
}'
$ for host in $(jq -r '.host' <<< "$hosts_list")
do
echo "$host"
done
host1-availabe_zone_A
host2-availabe_zone_B
host3-availabe_zone_A
使用-r
选项使其输出原始字符串,而不是用双引号引起来的JSON字符串。
除非您故意需要对值进行单词拆分和通配符匹配,否则不要忘记引用变量。
答案 2 :(得分:0)
在program.jq中具有以下内容:
# bag of words
def bow(stream):
reduce stream as $word ({}; .[($word|tostring)] += 1);
bow(inputs | .host | sub("^.*-availabe";"availabe"))
调用:
jq -n -f program.jq input.json
产生
{
"availabe_zone_A": 2,
"availabe_zone_B": 1
}
如果您确实想要STRING-> N格式的输出, 在命令行选项中添加-r,并添加以下内容 到program.jq的两行:
| to_entries[]
| "\(.key) --> \(.value)"