簡體   English   中英

jq通過特定鍵計算json中的項目數

[英]jq count the number of items in json by a specific key

以下是我的json文件中的前兩項

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

我想計算出現在json中的每個ItmId的項目數。 例如,在我的json文件中,帶有“ ItmId” 1694738780的項目出現10次,帶有“ ItmId” 1347809133的項目出現14次。 然后像這樣返回一個json

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

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

謝謝!!!

這是一個解決方案(假設輸入是有效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則使用內存inputs方法稍微更節省內存。 但是在這種情況下,請使用-n而不是-s,然后將上面的第一行替換為:[inputs | {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 .

這是一個超高效的解決方案-特別是不需要排序。 以下實現需要帶有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}

這是一個使用reducesetpathgetpath進行聚合並使用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 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM