Json jq添加额外的变量前缀

Json jq添加额外的变量前缀,json,key,jq,key-value,Json,Key,Jq,Key Value,我最近问了几个关于jq的问题,有了这些完美的答案,我学到了很多。我希望这个问题还是有可能的 { "kind":"ServiceList", "apiVersion":"v1", "items":[ { "spec":{ "ports":[ {

我最近问了几个关于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(";")
关于第一组要求,这有两个问题:

.items[].spec
| [.ports
   | range(0;length) as $ix
   | .[$ix]
   | to_entries
   | map("port\($ix+1|leadingZeros(2))\(.key)=\(.value)")
   | join(";") ]
| join(";")
a) 它产生三个独立的字符串; b) “port01”硬连线到前缀中

第一个问题可以通过将相关的子表达式包装在方括号中,然后再次使用join(;)来解决

为了解决第二个问题,有一个用于插入前导零的helper函数是有帮助的。以下内容就足够了:

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命令行选项,这将为每个端口生成一行:

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新手。。。我拥有的最好的是“.items[].spec.ports[]].\to| map(“port01(.key)=(.value)”)| join(;”)哇,太棒了。我现在可以完全理解第一个修复。我可能需要一段时间来消化第二个补丁。