Ken*_*ici 3 parsing json key environment-variables jq
我正在尝试从JSON输出中解析环境变量docker inspect.令人讨厌的是,这些环境变量不会作为有用的键值对返回.它们只是一个x = y字符串的数组.这是输出的相关片段:
[
{
"Config": {
"Env": [
"JENKINS_HOST=1.2.3.4",
"JENKINS_INSTANCE=tea",
"JENKINS_NAME=Enterprise Architecture Tools",
"JENKINS_VERSION=2.46.2",
"JENKINS_PROTOCOL=http"
]
}
}
]
Run Code Online (Sandbox Code Playgroud)
我想将该数组转换为这样的:
{
"Config": {
"Env": {
"JENKINS_HOST": "1.2.3.4",
"JENKINS_INSTANCE": "tea",
"JENKINS_NAME": "Enterprise Architecture Tools",
"JENKINS_VERSION": "2.46.2",
"JENKINS_PROTOCOL": "http"
}
}
}
Run Code Online (Sandbox Code Playgroud)
这样,我可以使用命令jq '.[] | .Config.Env.JENKINS_HOST'来获取我关心的值.我无法弄清楚如何实现这一目标.
选择数据相对容易,甚至将键和值拆分为单独的元素.例如,如果我使用jq '.[] | .Config.Env | .[] | split("=")',我会得到这样的数据:
[
"JENKINS_HOST",
"1.2.3.4"
]
[
"JENKINS_INSTANCE",
"tea"
]
[
"JENKINS_NAME",
"Enterprise Architecture Tools"
]
[
"JENKINS_VERSION",
"2.46.2"
]
[
"JENKINS_PROTOCOL",
"http"
]
Run Code Online (Sandbox Code Playgroud)
但是,我无法弄清楚如何将该数据转换为对象分配.看起来它应该是mapor的某种组合reduce,但我很难过.谁能指出我正确的方向?
要将两个字符串的数组(例如["k","v"])转换为对象,您可以编写:
{ (.[0]) : .[1] }
Run Code Online (Sandbox Code Playgroud)
所以你要写的东西如下:
map(.Config.Env |= (map( split("=") | { (.[0]) : .[1] } ) | add))
Run Code Online (Sandbox Code Playgroud)
抽象出数组到对象的功能使得解决方案更易于理解:
def a2o: map( split("=") | { (.[0]) : .[1] } ) | add;
map(.Config.Env |= a2o)
Run Code Online (Sandbox Code Playgroud)
match或capture代替split由于"="字符可能出现在每个var=value字符串的"值"部分中,因此split天真地使用可能不是一个好主意.假设您的jq支持正则表达式,这是一个更强大的替代方案:
match("([^=]*)=(.*)") | .captures | {(.[0].string) : .[1].string}
Run Code Online (Sandbox Code Playgroud)
或者,更简洁,也许更优雅:
[capture( "(?<key>[^:]*):(?<value>.*)" )] | from_entries
Run Code Online (Sandbox Code Playgroud)
index/1如果您的jq没有正则表达式支持,您可以index/1按照以下方式使用:
index("=") as $ix | {(.[:$ix]) : .[$ix+1:]}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1425 次 |
| 最近记录: |