2017-06-12 105 views
1

现在我有一个JSONJQ指定默认值某些情况

[ 
    { 
    "city": "SH", 
    "age": 0, 
    "count": 1 
    }, 
    { 
    "city": "SH", 
    "age": 20, 
    "count": 1 
    }, 
    { 
    "city": "SH", 
    "age": 40, 
    "count": 1 
    }, 
    { 
    "city": "BJ", 
    "age": 20, 
    "count": 2 
    }, 
    { 
    "city": "BJ", 
    "age": 30, 
    "count": 1 
    } 
] 

现在,我想每一个时代的一些数据可视化的目的计数阵列(见demo)。 e.g

# age data: [shCount, bjCount] 
age: 0, data:[1, 0] 
age: 20, data: [1, 2] 
age: 30, data: [0, 1] 
age: 40, data: [1, 0] 

如果城市没有年龄,给出一个默认值0。但是,如果城市没有年龄,就没有相关的JSON对象。

,所以我不能只是使用下面壳获得计数每一个时代的阵列,e.g

# without BJ value 
➜ ~ jq -c '.[] | select(.age==0) | [.city, .count]' foo.json 
["SH",1] 

➜ ~ jq -c '.[] | select(.age==20) | [.city, .count]' foo.json 
["SH",1] 
["BJ",2] 

所以,如果年龄为0,如何指定的0至BJ默认值?

回答

0

如果相关城市名事先不知道,那么下面的方法有很多可取之处,如果城市名称是字符串:

# Merge records having the same age 
def merge: 
    reduce .[] as $x ({}; . + ($x | { (.city) : .count})); 

# Create an object holding the default values: 
def zeros: 
    map({(tostring): 0}) | add; 

group_by(.age) 
| map({age: .[0].age, data: merge}) 
| (map(.data) | add | keys | zeros) as $zeros 
| map(.data = $zeros + .data) 

的上面的输出是具有形式的对象数组: {“age”:_,“data”:CITIES}

eg

{ 
    "age": 40, 
    "data": { 
     "BJ": 0, 
     "SH": 1 
    } 
    } 

现在很容易将CITIES转换为所需的格式。

2

为了清楚起见,用于合并同龄记录的帮助函数很有用。这是默认值的定义:

group_by(.age) 
| map({age: .[0].age, data: merge}) 

调用:

jq -c -f program.jq input.json 

结果:

[{"age":0,"data":[1,0]},{"age":20,"data":[1,2]},{"age":30,"data":[0,1]},{"age":40,"data":[1,0]}] 

def merge: 
    reduce .[] as $x ([0,0]; 
    if $x.city == "SH" then .[0] = $x.count else .[1] = $x.count end); 

接下来,我们按年龄只需要组记录

然后,您可以格式化结果无论你想要什么样的方式。

+0

谢谢,但我不能得到你的结果,但与错误消息:'jq:错误(在):不能迭代null(null)'。另外那里有很多城市呢? – zhuguowei

+0

您可能想要在不带-n选项的情况下调用jq。我已经相应地更新了答案。至于处理多个城市,我增加了另一个答案。 – peak

相关问题