it-swarm.com.ru

jQ подсчитать количество элементов в JSON по определенному ключу

Ниже приведены первые два элемента в моем файле JSON

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

Я хочу посчитать количество элементов по каждому ItmId, появившемуся в json. Например, элементы с «ItmId» 1694738780 появляются 10 раз, а элементы с «ItmId» 1347809133 появляются 14 раз в моем файле json. Затем верните JSON, как это

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

Я использую Bash. И предпочитаю сделать это полностью JQ. Но можно использовать другой метод.

Спасибо!!!

4
Eleanor

Вот одно решение (при условии, что входные данные являются потоком допустимых объектов JSON) и что вы вызываете jq с опцией -s:

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

Более эффективным способом использования памяти было бы использование inputs, если он есть у вашего jq; но в этом случае используйте -n вместо -s и замените первую строку выше на: [input | {ItemId: .Properties.ItmId}]

5
peak

Вот вариант, использующий lower , 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 }
0
jq170727

Вот суперэффективное решение - в частности, сортировка не требуется. Следующая реализация требует версию jq с inputs, но ее легко адаптировать для использования более ранних версий 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}
0
peak

Использование команды jq

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