使用 JQ 创建嵌套 Json 对象

Creating nested Json object using JQ

我需要获取以下 Json 输入的 Exon 中的值并将其拆分为“;”并转换为嵌套 JSON,如下面的预期输出部分

示例输入

  {  
   "regions":[  
      {  
         "metric":"GENE1",
         "value":[  
            {  
               "metric":"Exons",
               "value":[  
                  "GENE1;chr1;45656;5656667"    
               ],
               "type":"set"
            },
            {  
               "metric":"Precent_no_call",
               "value":4.22623,
               "type":"simple"
            },
            {  
               "metric":"Total_NoCall_bases",
               "value":112533,
               "type":"simple"
            }
         ],
         "type":"metrics-set"
      },
      {  
         "metric":"GENE2",
         "value":[  
            {  
               "metric":"Exons",
               "value":[  
                  "GENE2_Exon5;chr1;45656;5656667",
                  "GENE2_Exon10;chr1;45656;5656667"                 
               ],
               "type":"set"
            },
            {  
               "metric":"Precent_no_call",
               "value":0.746464,
               "type":"simple"
            },
            {  
               "metric":"Total_NoCall_bases",
               "value":16842,
               "type":"simple"
            }
         ],
         "type":"metrics-set"
      }
   ]
}

预期输出

{  
   "regions":[  
      {  
         "metric":"GENE1",
         "value":[  
            {  
               "metric":"Exons",
               "value":[  
                  "GENE1",
                  {  
                     "chromosome":"chr1",
                     "start":45656,
                     "end":5656667
                  }
               ],
               "type":"set"
            },
            {  
               "metric":"Precent_no_call",
               "value":4.22623,
               "type":"simple"
            },
            {  
               "metric":"Total_NoCall_bases",
               "value":112533,
               "type":"simple"
            }
         ],
         "type":"metrics-set"
      },
      {  
         "metric":"GENE2",
         "value":[  
            {  
               "metric":"Exons",
               "value":[  
                  "GENE2_Exon5",
                  {  
                     "chromosome":"chr1",
                     "start":45656,
                     "end":5656667
                  },
                  "GENE2_Exon10",
                  {  
                     "chromosome":"chr1",
                     "start":45656,
                     "end":5656667
                  }
               ],
               "type":"set"
            },
            {  
               "metric":"Precent_no_call",
               "value":0.746464,
               "type":"simple"
            },
            {  
               "metric":"Total_NoCall_bases",
               "value":16842,
               "type":"simple"
            }
         ],
         "type":"metrics-set"
      }
   ]
}

注意

另外,这与这里的问题有关:-

提前感谢您的帮助。

我从逗号分隔的输入文件中尝试的解决方案(参见我发布的另一个问题)

def parse:
  [
      inputs                     # read lines
    | split(",")                 # split into columns
    | select(length>0)           # eliminate blanks
    | .[:1] + [.[1:-3]] + .[-3:] # normalize columns

  ]
;
def simple(n;v): {metric:n, value:v|tonumber, type:"simple"};
def set(n;v):    {metric:n, value:v,          type:"set"};
def chr(c;s;e):  {chromsome:c, start:s, end:e}; 
def region:
  set(.[0]; [
      set("Exons";  (.[1] | tostring | split(";") |.[0]); 
      chr((.[1] | tostring | split(";") |.[1]),(.[1] | tostring | split(";") |.[2]),(.[1] | tostring | split(";") |.[3]))
     ]

     ),
      simple("Fraction of bases"; .[5]),
      simple("Total_bases"; .[6])
    ]
  )
;
{
   "Regions": parse | map(region)
}

我无法循环并递归读取。

由于低级需求已经足够明确,我组装了以下解决方案,其行为与示例完全一致。但是,更高级别的要求相当粗略,因此您可能需要进行一些调整。

低级需求(关于字符串转换)可以实现如下:

# Input: a string
def gene2object:
  split(";")
  | [.[0], { chromosome: .[1], 
             start: (.[2]|tonumber),
             end:   (.[3]|tonumber)} ];

一个解决方案现在可以很简单地写成如下:

walk( if type == "object" and .metric == "Exons" 
      then .value |= (map(gene2object)|add) 
      else .
      end )

标准调用(沿行:jq -f program.jq input.json)产生的输出与描述的完全一样,所以我不会在这里重复。

如果你的jq没有walk/1,那么你可以从https://github.com/stedolan/jq/blob/master/src/builtin.jq中获取它的官方定义 即搜索:def walk