繁体   English   中英

使用 jq 访问嵌套 json 的第一个键并获取其值

[英]Access to first key of a nested json using jq and obtain its value

我有以下 JSON:

{
    "query": "rest ec",
    "elected_facts_mapping": {
        "AWS": {
            "ECS": {
                "attachments": [
                    "restart_ecs"
                ],
                "text": [
                    "Great!"
                ]
            }
        }
    },
    "top_facts_mapping": {
        "AWS": {
            "ECS": {
                "attachments": [
                    "restart_ecs"
                ],
                "text": [
                    "Great!"
                ]
            },
            "EC2": {
                "attachments": [
                    "create_ec2"
                ],
                "text": [
                    "Awesome"
                ]
            }
        },
        "GitHub": {
            "Pull": {
                "attachments": [
                    "pull_req"
                ],
                "text": [
                    "Be right on it"
                ]
            }
        },
        "testtttt": {
            "test": {
                "attachments": [
                    "hello_world"
                ],
                "text": [
                    "Be right on it"
                ]
            }
        },
        "fgjgh": {
            "fnfgj": {
                "attachments": [
                    "hello_world"
                ],
                "text": [
                    "Be right on it"
                ]
            }
        },
        "tessttertre": {
            "gfdgfdgfd": {
                "attachments": [
                    "hello_world"
                ],
                "text": [
                    "Great!"
                ]
            }
        }
    },
    "elected_facts_with_prefix_text": null
}

我想访问top_facts_mapping's第一个密钥AWS和它的第一个密钥ECS

我正在尝试这样做(在我的 DSL 中):

'.span | fromjson'
'.span_data.top_facts_mapping | keys[0]'
'.span_data.top_facts_mapping[${top_facts_prepare_top_fact_topic}] | keys[0]'
'.top_facts_prepare_top_fact_topic_subtopic[${top_facts_prepare_top_fact_topic}][${top_facts_prepare_top_fact_topic_subtopic}]'

您可以使用keys_unsorted内置函数,因为底层 object 是字典而不是列表

.top_facts_mapping | keys_unsorted[0] as $k | .[$k] | .[keys_unsorted[0]]

上面的过滤器可以用一个简单的 function 重写

def get_firstkey_val: keys_unsorted[0] as $k | .[$k];
.top_facts_mapping | get_firstkey_val | get_firstkey_val

或者使用一些 jq 技巧,假设提供的路径top_facts_mapping保证存在

getpath([ paths | select(.[-3] == "top_facts_mapping" ) ] | first)

由于内置paths将根到叶路径构造为 arrays,我们所有包含倒数第二个字段(由.[-3]表示)的路径都作为"top_facts_mapping"返回其中的路径

从中first选择列表中的第一个实体,即下面的列表

[
  "top_facts_mapping",
  "AWS",
  "ECS"
]

使用getpath/1获取获取路径处的JSON值。

如果存在密钥top_facts_mapping不存在于 JSON 中的风险, getpath/1可能会返回如上所述的错误。 通过添加适当的检查来修复它

([ paths | select(.[-3] == "top_facts_mapping" ) ] | first) as $p | 
if $p | length > 0 then getpath($p) else empty end

您可以使用to_entries将 object 转换为键值对数组,然后使用[0].value将第一个值转换为 select

.top_facts_mapping | to_entries[0].value | to_entries[0].value
{
  "attachments": [
    "restart_ecs"
  ],
  "text": [
    "Great!"
  ]
}

演示

如果在某一级别 object 可能为空,您可以在每个to_entries加上try (可选地后跟一个catch子句)

这是一种基于流的方法,它使用--stream选项反汇编输入,过滤顶级.[0][0]上的“top_facts_mapping”键,截断 stream 以下降 3 级,使用 fromstream 重新组装fromstream ,并输出第first匹配项:

jq --stream -n 'first(fromstream(3| truncate_stream(inputs | select(.[0][0] == "top_facts_mapping"))))'
{
  "attachments": [
    "restart_ecs"
  ],
  "text": [
    "Great!"
  ]
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM