首页 > 解决方案 > How to parse multi properties with spacing in jq json bash script?

问题描述

I have a json string in the following format:

json='{"x": [{"y":"yyy1", "z":"zzz1 zzz1"}, {"y":"yyy2", "z":"zzz2 zzz2"}]}'

I'm trying to get an array var of all "y" and separate array of "z" with jq like

y_arr=$(echo "${json}" | jq '.x | [] | .y') # => outputs 2 array elements 
y_arr=$(echo "${json}" | jq '.x | [] | .z') # => outputs 4 array elements due to space

Do you have any idea how to fix this? Also, do you know any better way of parsing the json as single key/value array instead of two separate arrays?

标签: jsonbashshellparsingjq

解决方案


假设您的 bash 具有readarray(aka mapfile) 并且 bash 数组值是有效的 JSON 是可以接受的,您可以编写:

readarray z_array < <(echo "${json}" | jq -c '.x[] | .z') 

使用您的 $json,这将产生一个 JSON 字符串数组(带引号)。

壳循环

如果您的 shell 不支持readarray,那么您可以使用 jq 的相同调用,但在 bash 循环中读取值,例如:

declare -a array
while read v
do
    array+=("$v")
done < <(echo "${json}" | jq -c '.x[] | .z') 

字符串

如果所有 .z 值都是 JSON 字符串,那么如果这些字符串没有嵌入换行符,并且您希望 bash 数组值是“原始”字符串(而不是 JSON 字符串),则可以添加 -r 选项调用 jq。

关联数组

如果您的 bash 支持关联数组,请考虑:

declare -A a
i=0
while read v
do
    i=$((i+1))
    a["$v"]=$i
done < <(echo "${json}" | jq -c '.x[].z') 

declare -p a

for i in "${!a[@]}" ; do
  echo $i
done    

这会产生:

declare -A a=(["\"zzz2 zzz2\""]="2" ["\"zzz1 zzz1\""]="1" )
"zzz2 zzz2"
"zzz1 zzz1"

推荐阅读