jq按特定键

时间:2017-07-18 15:17:33

标签: json bash command-line count jq

以下是我的json文件中的前两项

{
"ReferringUrl": "N",
"OpenAccess": "0",
"Properties": {
    "ItmId": "1694738780"
   }
}
{
"ReferringUrl": "L",
"OpenAccess": "1",
"Properties": {
    "ItmId": "1347809133"
  }
}

我想计算每个ItmId出现在json中的项目数。例如,使用" ItmId" 1694738780出现了10次,而#34; ItmId" 1347809133在我的json文件中出现14次。然后像这样返回一个json

{"ItemId": "1694738780",
 "Count":  10
}
{"ItemId": "1347809133",
 "Count":  14
}

我正在使用bash。并且更喜欢完全由jq完成。但是可以使用其他方法。

谢谢!!!

4 个答案:

答案 0 :(得分:7)

这是一个解决方案(假设输入是有效JSON对象的流),并使用-s选项调用jq:

map({ItemId: .Properties.ItmId})             # extract the ItmID values
| group_by(.ItemId)                          # group by "ItemId"
| map({ItemId: .[0].ItemId, Count: length})  # store the counts
| .[]                                        # convert to a stream

如果你的jq拥有它,那么更有效的方法就是使用inputs;但在这种情况下,使用-n代替-s,并将上面的第一行替换为:[inputs | {ItemId:.Properties.ItmId}]

答案 1 :(得分:1)

使用jq命令

cat json.txt | jq '.Properties .ItmId' | sort | uniq -c | awk -F " " '{print "{\"ItmId\":" $2 ",\"count\":" $1"}"}'| jq .

答案 2 :(得分:1)

这是一种超高效的解决方案 - 特别是不需要排序。以下实现需要具有inputs的jq版本,但很容易使程序适应使用早期版本的jq。如果使用以下内容,请记住使用-n命令行选项:

# Count the occurrences of distinct values of (stream|tostring).
# To avoid unwanted collisions, or to recover the exact values,
# consider using tojson
def counter(stream):
  reduce stream as $s ({}; .[$s|tostring] += 1);

counter(inputs | .Properties.ItmId)
| to_entries[]
| {ItemId: (.key), Count: .value}

答案 3 :(得分:1)

以下是使用 reduce setpath getpath 进行聚合并使用 to_entries 执行此操作的变体假设你运行jq为

的最终格式
jq --slurp -f query.jq < data.json

data.json 包含您的数据, query.jq 包含

  map(.Properties.ItmId)
| reduce .[] as $i (
    {}; setpath([$i]; getpath([$i]) + 1)
  )
| to_entries | .[] | { "ItemId": .key, "Count": .value }