jq 添加额外的变量前缀
jq add additional variable prefix
我最近问了几个 jq 配对问题,并且有了所有完美的答案,我确实学到了很多东西。我希望这个问题仍然是可能的..
{
"kind":"ServiceList",
"apiVersion":"v1",
"items":[
{
"spec":{
"ports":[
{
"name":"https",
"protocol":"TCP",
"port":443,
"targetPort":6443
},
{
"name":"http",
"protocol":"TCP",
"port":80,
"targetPort":8080
}
],
"clusterIP":"10.233.0.1",
"type":"ClusterIP",
"sessionAffinity":"None"
},
"status":{
"loadBalancer":{
}
}
},
{
"spec":{
"ports":[
{
"protocol":"TCP",
"port":80,
"targetPort":80,
"nodePort":40001
}
],
"selector":{
"run":"my-httpd"
},
"clusterIP":"10.233.27.102",
"type":"NodePort",
"sessionAffinity":"None",
"externalTrafficPolicy":"Cluster"
},
"status":{
"loadBalancer":{
}
}
}
]
}
期望的输出是:
port01name=https;port01protocol=TCP;port01port=443;port01targetPort=6443;port02name=http;port02protocol=TCP;port02port=80;port02targetPort=8080
port01protocol=TCP;port01port=80;port01targetPort=80;port01nodePort=40001
它基本上将每个项目的多个端口连接成一行,并将额外的端口{n}作为前缀。
在jq里还能做吗?
或者,输出可以在下面,然后我尝试操作它。
portname=https;portprotocol=TCP;portport=443;porttargetPort=6443;portname=http;portprotocol=TCP;portport=80;porttargetPort=8080
portprotocol=TCP;portport=80;porttargetPort=80;portnodePort=400
在您的引导下,让我们开始:
.items[] .spec.ports[] | to_entries | map("port01\(.key)=\(.value)") | join(";")
关于第一组要求,这有两个问题:
a) 它产生三个独立的字符串;
b) “port01”硬连接到前缀中。
第一个问题可以通过将相关子表达式括在方括号中,然后再次使用 join(";") 来解决。
要解决第二个问题,有一个插入前导零的辅助函数会有所帮助。以下内容就足够了:
def leadingZeros($n): tostring | "0"*($n - length) + .;
现在可以根据第一组需求用这个来解决问题:
.items[].spec
| [.ports
| range(0;length) as $ix
| .[$ix]
| to_entries
| map("port\($ix+1|leadingZeros(2))\(.key)=\(.value)")
| join(";") ]
| join(";")
全球指数
如果要求修改为要求端口索引是全局的,我们可以采用以下变体:
def addIndex(stream): foreach stream as $x (0; .+1; [., $x]);
addIndex(.items[].spec.ports[])
| (.[0]|leadingZeros(2)) as $ix
| .[1]
| to_entries
| map("port\($ix)\(.key)=\(.value)")
| join(";")
使用 -r command-line 选项,每个端口生成一行:
port01name=https;port01protocol=TCP;port01port=443;port01targetPort=6443
port02name=http;port02protocol=TCP;port02port=80;port02targetPort=8080
port03protocol=TCP;port03port=80;port03targetPort=80;port03nodePort=40001
我最近问了几个 jq 配对问题,并且有了所有完美的答案,我确实学到了很多东西。我希望这个问题仍然是可能的..
{
"kind":"ServiceList",
"apiVersion":"v1",
"items":[
{
"spec":{
"ports":[
{
"name":"https",
"protocol":"TCP",
"port":443,
"targetPort":6443
},
{
"name":"http",
"protocol":"TCP",
"port":80,
"targetPort":8080
}
],
"clusterIP":"10.233.0.1",
"type":"ClusterIP",
"sessionAffinity":"None"
},
"status":{
"loadBalancer":{
}
}
},
{
"spec":{
"ports":[
{
"protocol":"TCP",
"port":80,
"targetPort":80,
"nodePort":40001
}
],
"selector":{
"run":"my-httpd"
},
"clusterIP":"10.233.27.102",
"type":"NodePort",
"sessionAffinity":"None",
"externalTrafficPolicy":"Cluster"
},
"status":{
"loadBalancer":{
}
}
}
]
}
期望的输出是:
port01name=https;port01protocol=TCP;port01port=443;port01targetPort=6443;port02name=http;port02protocol=TCP;port02port=80;port02targetPort=8080
port01protocol=TCP;port01port=80;port01targetPort=80;port01nodePort=40001
它基本上将每个项目的多个端口连接成一行,并将额外的端口{n}作为前缀。
在jq里还能做吗?
或者,输出可以在下面,然后我尝试操作它。
portname=https;portprotocol=TCP;portport=443;porttargetPort=6443;portname=http;portprotocol=TCP;portport=80;porttargetPort=8080
portprotocol=TCP;portport=80;porttargetPort=80;portnodePort=400
在您的引导下,让我们开始:
.items[] .spec.ports[] | to_entries | map("port01\(.key)=\(.value)") | join(";")
关于第一组要求,这有两个问题:
a) 它产生三个独立的字符串; b) “port01”硬连接到前缀中。
第一个问题可以通过将相关子表达式括在方括号中,然后再次使用 join(";") 来解决。
要解决第二个问题,有一个插入前导零的辅助函数会有所帮助。以下内容就足够了:
def leadingZeros($n): tostring | "0"*($n - length) + .;
现在可以根据第一组需求用这个来解决问题:
.items[].spec
| [.ports
| range(0;length) as $ix
| .[$ix]
| to_entries
| map("port\($ix+1|leadingZeros(2))\(.key)=\(.value)")
| join(";") ]
| join(";")
全球指数
如果要求修改为要求端口索引是全局的,我们可以采用以下变体:
def addIndex(stream): foreach stream as $x (0; .+1; [., $x]);
addIndex(.items[].spec.ports[])
| (.[0]|leadingZeros(2)) as $ix
| .[1]
| to_entries
| map("port\($ix)\(.key)=\(.value)")
| join(";")
使用 -r command-line 选项,每个端口生成一行:
port01name=https;port01protocol=TCP;port01port=443;port01targetPort=6443
port02name=http;port02protocol=TCP;port02port=80;port02targetPort=8080
port03protocol=TCP;port03port=80;port03targetPort=80;port03nodePort=40001