Shell脚本-将jq数组输出分配给SHELL数组

时间:2019-05-10 16:25:58

标签: shell zsh jq

我正在使用jq来解析json文件-

json文件看起来像-

{
  "values": [
    {
      "email": "user1@domain.com",
      "id": "USER1_ID"
    },{
      "email": "user2@domain.com",
      "id": "USER2_ID"
    },
    .
]
}

我可以通过以下ID进行打印/迭代

for k in $(cat input.json | jq .values | jq .[].id); do
    echo $k
done

这会按预期打印每个ID。

但是,我想要的是在循环中同时访问电子邮件和ID。

我试图将值分配给SHELL变量,如下所示-

emails=$(cat input.json | jq .values | jq .[].email)
ids=$(cat input.json | jq .values | jq .[].id)

这在大多数情况下都可以工作,但是ids也可以有空格,这打破了这一点。

从本质上讲,我可能必须要有2个循环,一个用于email,另一个用于id,然后将值分配给循环中的数组

   i=0
    for k in $(cat input.json | jq .values | jq .[].id); do
            ids[$i]=$k
            i=$(($i +1)) 
        done

i=0
for k in $(cat input.json | jq .values | jq .[].email); do
        emails[$i]=$k
        i=$(($i +1)) 
    done

一旦我将两个值都放在数组中,就可以并行遍历两个值。

我不是Shell专家,所以我想知道是否有任何巧妙的方法可以减少循环/代码行。

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

将每个email-id对作为与jq逗号分隔的列表输出,并使用while循环将它们读入变量:

while IFS=',' read -r email id; do
  echo "$email"
  echo "$id"
done <<EOF
$(jq -r '.values[] | "\(.email),\(.id)"' file)
EOF

答案 1 :(得分:2)

假设变量没有嵌入的回车符,则可以通过为每个变量使用单独的read命令来节省很多IFS麻烦,例如:

jq -r '.values[] | (.email, .id)'  input.json |
while IFS= read -r email ; do
    IFS= read -r id 
    echo "email=$email and id=$id"
done