2016-08-18 50 views
2

使用JQ的JSON我有以下的JSON改变在bash

{ 
    "name" : "qwerty", 
    "values" :[ 
    { 
     "field1" : [ 
      "val1" 
      ], 
     "field2" : [ 
      "val2" 
      ], 
     "name1" : [["a", "b"], ["c", "d"]] 
    }, 
    { 
     "field1" : [ 
      "val3" 
      ], 
     "field2" : [ 
      "val4" 
      ], 
     "name1" : [["a", "b"], ["c", "d"]] 
    }, 
    { 
     "field1" : [ 
      "val5" 
      ], 
     "field2" : [ 
      "val6" 
      ], 
     "name1" : [["a", "b"], ["c", "d"]] 
    } 
    ] 
} 

我需要上述JSON更改为以下使用JQ在bash

{ 
    "name" : "qwerty", 
    "values" :[ 
    { 
     "field1" : "val1", 
     "field2" : "val2", 
     "new_name" : [["a", "b"], ["c", "d"]] 
    }, 
    { 
     "field1" : "val3", 
     "field2" : "val4", 
     "new_name" : [["a", "b"], ["c", "d"]] 
    }, 
    { 
     "field1" : "val5", 
     "field2" : "val6", 
     "new_name" : [["a", "b"], ["c", "d"]] 
    } 
    ] 

} 

我在这里面临着以下问题:

我试着用标签值解析内部json,并用空格替换'['']',但是,当我尝试将“值”放入列表形式的变量中时,jq是美化和然后显示每个作为数组元素的新行。

values数组中的内部jsons的数量不固定。

有人可以帮助我构建jq语句在bash中运行以进行必要的更改。

+1

指出了这一点@fedorqui日Thnx,纠正问题 – vamsi

+0

你知道,这是专门'.values []。field1'和'.values []。field2'要更改,或者是任何应该折叠为单个值的单例列表? – chepner

+0

是“field1,field2,name”在每个json中都是固定的。但是jsons的数量并不固定。 – vamsi

回答

1

这应该工作;我不知道如果有重构分配到field1field2方式:

jq '.values[] |= (.field1=.field1[0] | .field2=.field2[0])' tmp1.json 
+0

另一种选择是使用新值创建对象并合并它。但我认为这比作业更丑陋,可能更具破坏性。 –

+0

仅仅基于这个名字,我认为'foreach'可能是相关的,但我似乎无法围绕它如何工作。我只能用'jq'.values [] |(foreach [“field1”,“field2”]作为$ f(empty;。[$ f] =。[$ f] [ 0];空))至少符合的'tmp1.json';它不产生输出。 – chepner

+0

在我的脑海中,我看到它的方式是'foreach'就像'减少',但有一个额外的提取部分。因此,在您的评论中的示例中,您使用空值初始化,并尝试为其分配值。但是空是空的,所以它在每次迭代中都不会产生结果。然后对于提取部分,您将提取为空,所以没有任何东西来自它。通过这种方法,您可以坚持使用'reduce'(稍作调整):'.values [] | = reduce(“field1”,“field2”)为$ f(。;。[$ f] =。[ $ f] [0])' –

2

下面的代码片段应该做你想要什么:

jq '{ 
    "name": .name, 
    "values": [ 
     { 
      "field1" : .values[0].field1[0], 
      "field2" : .values[0].field2[0], 
      "New_name": .values[0].name1 
     }, 
     { 
      "field1" : .values[1].field1[0], 
      "field2" : .values[1].field2[0], 
      "new_name" : .values[1].name1 
     }, 
     { 
      "field1" : .values[2].field1[0], 
      "field2" : .values[2].field2[0], 
      "new_name" : .values[2].name1 
     } 
    ] 
}' < /tmp/input.json 

编辑

由于对象的数量不固定下面的代码片段会做:

jq '{ 
     "name" : .name, 
     "values" : [ 
       .values[] as $in | 
       { 
         "field1" : $in.field1[0], 
         "field2" : $in.field2[0], 
         "new_name" : $in.name1 
       } 
     ] 

}' < /tmp/input.json 
+0

thnx快速响应。但是,values数组中的内部jsons的数量并不固定。 – vamsi

0

这里是另一种解决方案。

.values |= map({ 
    field1: .field1[0], 
    field2: .field2[0], 
    new_name: .name1 
    })