使用 jq 将 x=y 对转换为键/值对 [英] Use jq to turn x=y pairs into key/value pairs

查看:23
本文介绍了使用 jq 将 x=y 对转换为键/值对的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从 docker inspect 的 JSON 输出中解析环境变量.令人讨厌的是,这些环境变量不会作为有用的键值对返回.它们只是 x=y 字符串的数组.这是输出的相关片段:

I'm trying to parse environment variables from the JSON output of docker inspect. Annoyingly, those environment variables aren't returned as useful key-value pairs. They're just an array of x=y strings. Here's a relevant snippet of the output:

[
    {
        "Config": {
            "Env": [
                "JENKINS_HOST=1.2.3.4",
                "JENKINS_INSTANCE=tea",
                "JENKINS_NAME=Enterprise Architecture Tools",
                "JENKINS_VERSION=2.46.2",
                "JENKINS_PROTOCOL=http"
            ]
        }
    }
]

我想将该数组转换成这样的:

I would like to convert that array into something like this:

{
  "Config": {
    "Env": {
      "JENKINS_HOST": "1.2.3.4",
      "JENKINS_INSTANCE": "tea",
      "JENKINS_NAME": "Enterprise Architecture Tools",
      "JENKINS_VERSION": "2.46.2",
      "JENKINS_PROTOCOL": "http"
    }
  }
}

这样,我可以使用像 jq '.[] | 这样的命令.Config.Env.JENKINS_HOST' 来获取我关心的值.我不知道如何做到这一点.

That way, I can use a command like jq '.[] | .Config.Env.JENKINS_HOST' to get the values that I care about. I can't figure out how to accomplish this.

选择数据甚至将键和值拆分为单独的元素相对容易.例如,如果我使用 jq '.[] |.Config.Env |.[] |split("=")',我得到这样的数据:

It's relatively easy to select the data and even split the key and value into separate elements. For instance, if I use jq '.[] | .Config.Env | .[] | split("=")', I get data like this:

[
  "JENKINS_HOST",
  "1.2.3.4"
]
[
  "JENKINS_INSTANCE",
  "tea"
]
[
  "JENKINS_NAME",
  "Enterprise Architecture Tools"
]
[
  "JENKINS_VERSION",
  "2.46.2"
]
[
  "JENKINS_PROTOCOL",
  "http"
]

但是,我不知道如何将这些数据转换为对象分配.似乎它应该是 mapreduce 的某种组合,但我很难过.谁能指出我正确的方向?

However, I can't figure out how to turn that data into an object assignment. It seems like it should probably be some combination of map or reduce, but I'm stumped. Can anyone point me in the right direction?

推荐答案

要将包含两个字符串(例如 ["k", "v"])的数组转换为对象,可以这样写:

To convert an array of two strings (e.g. ["k", "v"]) to an object, you can write:

{ (.[0]) : .[1] }

所以你会想写这样的东西:

So you'll want to write something like:

 map(.Config.Env |= (map( split("=") | { (.[0]) : .[1] } ) | add))

a2o

抽象出数组到对象的功能使解决方案更容易理解:

a2o

Abstracting out the array-to-object functionality makes the solution a bit more digestible:

def a2o: map( split("=") | { (.[0]) : .[1] } ) | add;

map(.Config.Env |= a2o)

使用 matchcapture 代替 split

由于="字符可能出现在每个 var=value 字符串的值"部分中,因此天真地使用 split 可能不是这样的好点子.假设您的 jq 支持正则表达式,这是一个更强大的替代方案:

Using match or capture instead of split

Since it is possible for an "=" character to appear in the "value" part of each var=value string, using split naively might not be such a great idea. Here is a more robust alternative, assuming your jq supports regular expressions:

match("([^=]*)=(.*)") | .captures | {(.[0].string) : .[1].string}

或者,更简洁,也许更优雅:

Or, slightly more succinctly and perhaps elegantly:

[capture( "(?<key>[^:]*):(?<value>.*)" )] | from_entries

index/1

如果您的 jq 不支持正则表达式,您可以使用 index/1,如下所示:

index("=") as $ix | {(.[:$ix]) : .[$ix+1:]}

这篇关于使用 jq 将 x=y 对转换为键/值对的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆