jq按特定键计算json中的项目数

时间:2021-06-26 00:15:05

The following is the first two items in my json file

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

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

I want to count the number of items by each ItmId appeared in the json. For example, items that with "ItmId" 1694738780 appears 10 times and items with "ItmId" 1347809133 appears 14 times in my json file. Then return a json like this

我想计算每个ItmId出现在json中的项目数。例如,带有“ItmId”1694738780的项目出现10次,带有“ItmId”1347809133的项目在我的json文件中出现14次。然后像这样返回一个json

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

I am using bash. And prefer do this totally by jq. But it's ok to use other method.

我正在使用bash。而且更喜欢用jq完成这个。但是可以使用其他方法。

Thank you!!!

4 个解决方案

#1


4  

Here's one solution (assuming the input is a stream of valid JSON objects) and that you invoke jq with the -s option:

这是一个解决方案(假设输入是有效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

A more memory-efficient approach would be to use inputs if your jq has it; but in that case, use -n instead of -s, and replace the first line above by: [inputs | {ItemId: .Properties.ItmId} ]

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

#2


0  

Using jq command

使用jq命令

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

#3


0  

Here's a super-efficient solution -- in particular, no sorting is required. The following implementation requires a version of jq with inputs but it is easy to adapt the program to use earlier versions of jq. Please remember to use the -n command-line option if using the following:

这是一种超高效的解决方案 - 特别是不需要排序。以下实现需要带有输入的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}

#4


0  

Here is a variation using reduce, setpath and getpath to do the aggregation and to_entries to do the final formatting which assumes you run jq as

这是使用reduce,setpath和getpath进行聚合的变体,使用to_entries进行最终格式化,假定您运行jq as

jq --slurp -f query.jq < data.json

where data.json contains your data and query.jq contains

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

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

#1


4  

Here's one solution (assuming the input is a stream of valid JSON objects) and that you invoke jq with the -s option:

这是一个解决方案(假设输入是有效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

A more memory-efficient approach would be to use inputs if your jq has it; but in that case, use -n instead of -s, and replace the first line above by: [inputs | {ItemId: .Properties.ItmId} ]

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

#2


0  

Using jq command

使用jq命令

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

#3


0  

Here's a super-efficient solution -- in particular, no sorting is required. The following implementation requires a version of jq with inputs but it is easy to adapt the program to use earlier versions of jq. Please remember to use the -n command-line option if using the following:

这是一种超高效的解决方案 - 特别是不需要排序。以下实现需要带有输入的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}

#4


0  

Here is a variation using reduce, setpath and getpath to do the aggregation and to_entries to do the final formatting which assumes you run jq as

这是使用reduce,setpath和getpath进行聚合的变体,使用to_entries进行最终格式化,假定您运行jq as

jq --slurp -f query.jq < data.json

where data.json contains your data and query.jq contains

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

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