jq在复杂的json文件中根据y获取x的值

时间:2017-05-11 19:51:59

标签: json jq

jq再次罢工。尝试根据json文件中的DATABASES_DEFAULT获取name的值,该文件中包含大量name s并且我完全丢失了。

我的文件看起来如下(aws ecs describe-task-definition的输出)只是复杂得多;我把它剥离到最基本的例子,我可以在那里结构仍然完好无损。

{
    "taskDefinition": {
        "status": "bar", 
        "family": "bar2",  
        "volumes": [], 
        "taskDefinitionArn": "bar3", 
        "containerDefinitions": [
            {
                "dnsSearchDomains": [], 
                "environment": [
                    {
                        "name": "bar4", 
                        "value": "bar5"
                    }, 
                    {
                        "name": "bar6", 
                        "value": "bar7"
                    },  
                    {
                        "name": "DATABASES_DEFAULT", 
                        "value": "foo"
                    }
                ], 
                "name": "baz", 
                "links": []
            },
            {
                "dnsSearchDomains": [], 
                "environment": [
                    {
                        "name": "bar4", 
                        "value": "bar5"
                    }, 
                    {
                        "name": "bar6", 
                        "value": "bar7"
                    },  
                    {
                        "name": "DATABASES_DEFAULT", 
                        "value": "foo2"
                    }
                ], 
                "name": "boo", 
                "links": []
            }
        ], 
        "revision": 1
    }
}

我需要DATABASES_DEFAULT name baz的值name。请注意,environment有很多密钥对,我特别谈到jq '.[] | select(.name==DATABASES_DEFAULT) | .value' 之外的密钥对。

我一直在修补这一点,但只是在意识到我不了解如何访问嵌套值之前已经走了这么远。

jq: error: DATABASES_DEFAULT/0 is not defined at <top-level>, line 1:
.[] | select(.name==DATABASES_DEFAULT) | .value
jq: 1 compile error

正在返回

name

显然,这a)不起作用,b)即使它确实如此,它也与<TargetFramework>netcoreapp1.1.1</TargetFramework> 值无关。我的想法是返回所有数据库默认值,然后用baz识别它,但我不知道这是否是正确的方法。

2 个答案:

答案 0 :(得分:2)

我喜欢把它想象成挖掘结构,所以首先打开外层:

.taskDefinition.containerDefinitions[]

现在选择你想要的那个:

select(.name =="baz")

打开内部结构:

.environment[]

选择所需的对象:

select(.name == "DATABASES_DEFAULT")

选择您想要的密钥:

.value

合在一起:

parse.jq

.taskDefinition.containerDefinitions[] |
select(.name =="baz")                  |
.environment[]                         |
select(.name == "DATABASES_DEFAULT")   |
.value

像这样运行:

<infile jq -f parse.jq

输出:

"foo"

答案 1 :(得分:1)

以下似乎有效:

.taskDefinition.containerDefinitions[] |
  select(
    select(
     .environment[] | .name == "DATABASES_DEFAULT"
    ).name == "baz"
  )

输出是name键映射到“baz”的对象。

$ jq '.taskDefinition.containerDefinitions[] | select(select(.environment[]|.name == "DATABASES_DEFAULT").name=="baz")' tmp.json
{
  "dnsSearchDomains": [],
  "environment": [
    {
      "name": "bar4",
      "value": "bar5"
    },
    {
      "name": "bar6",
      "value": "bar7"
    },
    {
      "name": "DATABASES_DEFAULT",
      "value": "foo"
    }
  ],
  "name": "baz",
  "links": []
}