代码之家  ›  专栏  ›  技术社区  ›  Pramod

使用JQ创建嵌套的Json对象

  •  -1
  • Pramod  · 技术社区  · 7 年前

    我需要获取以下Json输入的外显子中的值,并将其拆分为“;”并转换为嵌套的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"
          }
       ]
    }
    

    注释

    此外,这与这里的问题有关:- Converting comma separated file to nested objects json in jq

    提前谢谢你的帮助。

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

    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)
    }
    

    我无法循环并递归阅读。

    1 回复  |  直到 7 年前
        1
  •  1
  •   peak    7 年前

    由于底层需求足够清楚,我组装了以下解决方案,其行为与示例完全一致。然而,更高级别的要求相当粗略,因此您可能需要进行一些调整。

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

    # 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 )完全按照描述生成输出,因此我在这里不再重复。

    walk/1 ,则可以从 https://github.com/stedolan/jq/blob/master/src/builtin.jq 也就是说,搜索: def walk