使用jq将嵌套的JSON对象转换为数组到bash数组中

时间:2017-09-14 22:25:40

标签: json bash parsing jq

我正在做一些从根本上说错了但却看不出来的东西,有些人可以在这里用jq或JSON指出我的错吗?

我在数组“entries

中包含以下子对象
{
    "profile": {
        "name": "TesterRun1",
        "download": {
            "entries": [{
                    "ENTRY_A": "testserver1_place_com",
                    "store": "A",
                    "type": "direct"
                },
                {
                    "ENTRY_B": "testserver2_anotherplace_com",
                    "store": "B",
                    "type": "bypass"
                },
                {
                    "ENTRY_B": "testserver2_anotherplace_com",
                    "store": "A",
                    "type": "bypass"
                }
            ]
        }
    }
}

我希望使用以下查询将这些转换为bash通过jq函数“to_entries”可访问的数组,但到目前为止还没有!

jq 'to_entries|.[]|.profile.download.entries|select(.store=="A")|.[]'

您可以在此处看到JQ Play上没有任何内容返回 - enter link description here

请帮助我保持理智,我做错了什么

2 个答案:

答案 0 :(得分:0)

to_entries与将JQ结果暴露给bash没有任何关系。相反,它接受JSON对象中的每个条目并发出{"key": key, "value": value}对。

如果要识别和提取任意键,可以有用。例如:

#!/usr/bin/env bash

jq_script='
.profile.download.entries[]
| select(.store == "A")
| to_entries[]
| select(.key != "store")
| select(.key != "type")
| [.key, .value]
| @tsv
'

declare -A array=( )
while IFS=$'\t' read -r key value; do
  array[$key]=$value
done < <(jq -r "$jq_script")

# print array output
declare -p array

...当给出你对stdin的输入时,会发出(尽管在一行上,没有空格的变化):

declare -A array=([ENTRY_A]="testserver1_place_com"
                  [ENTRY_B]="testserver2_anotherplace_com" )

...我假设,因为在问题中没有任何更好的描述,是你真正想要的。

答案 1 :(得分:0)

这是一种稍微不同的方法(带有一些清理过的数据),它将message, name and stack. 的输出捕获到单独的列数组中。

jq

输出

#!/bin/bash
data='{
  "profile": {
    "name": "TesterRun1",
    "download": {
      "entries": [
        {
          "entry": "testserver1_place_com",
          "store": "A",
          "type": "direct"
        },
        {
          "entry": "testserver2_anotherplace_com",
          "store": "B",
          "type": "bypass"
        },
        {
          "entry": "testserver2_anotherplace_com",
          "store": "A",
          "type": "bypass"
        }
      ]
    }
  }
}'
filter='
        .profile.download.entries[]
      | select(.store == "A")
      | .entry, .store, .type
'      
declare -a ENTRY
declare -a STORE
declare -a TYPE
i=0
while read -r entry; read -r store; read -r type; do
    ENTRY[$i]="$entry"
    STORE[$i]="$store"
    TYPE[$i]="$type"
    i=$((i + 1))
done < <(jq -Mr "$filter" <<< "$data")
declare -p ENTRY STORE TYPE