以下は私のjsonファイルの最初の2つのアイテムです
{
"ReferringUrl": "N",
"OpenAccess": "0",
"Properties": {
"ItmId": "1694738780"
}
}
{
"ReferringUrl": "L",
"OpenAccess": "1",
"Properties": {
"ItmId": "1347809133"
}
}
Jsonに表示された各ItmIdごとにアイテムの数をカウントしたいと思います。たとえば、「ItmId」が1694738780のアイテムは10回出現し、「ItmId」が1347809133のアイテムはjsonファイルに14回出現します。次に、このようなjsonを返します
{"ItemId": "1694738780",
"Count": 10
}
{"ItemId": "1347809133",
"Count": 14
}
私はbashを使用しています。そして、これを完全にjqで行うことをお勧めします。ただし、他の方法を使用しても問題ありません。
ありがとうございました!!!
これが1つの解決策(入力が有効な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
を使用することです。ただし、その場合は、-sの代わりに-nを使用し、上記の最初の行を次のように置き換えます。 {ItemId:.Properties.ItmId}]
上記のソリューションは組み込みgroup_by
、これは便利ですが、簡単に回避できる非効率につながります。次のcounter
を使用すると、非常に効率的なソリューションを簡単に作成できます。
def counter(stream):
reduce stream as $s ({}; .[$s|tostring] += 1);
-nコマンドラインオプションを使用し、次のように適用します。
counter(inputs | .Properties.ItmId)
これはカウントの辞書につながります:
{
"1694738780": 1,
"1347809133": 1
}
このようなディクショナリは、OPによって想定されているシングルトンオブジェクトのストリームよりもおそらく便利ですが、ストリームなどが必要な場合は、上記を次のように変更できます。
counter(inputs | .Properties.ItmId)
| to_entries[]
| {ItemId: (.key), Count: .value}
Jqコマンドの使用
cat json.txt | jq '.Properties .ItmId' | sort | uniq -c | awk -F " " '{print "{\"ItmId\":" $2 ",\"count\":" $1"}"}'| jq .
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 }
これは非常に効率的なソリューションです。特に、並べ替えは必要ありません。次の実装では、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}