想根據陣列大小(10000/50000 等)將一個巨大的 json 檔案 ~20GB 分割成更小的資料塊。
輸入:
{"recDt":"2021-01-05",
"country":"US",
"name":"ABC",
"number":"9828",
"add": [
{"evnCd":"O","rngNum":"1","state":"TX","city":"ANDERSON","postal":"77830"},
{"evnCd":"O","rngNum":"2","state":"TX","city":"ANDERSON","postal":"77832"},
{"evnCd":"O","rngNum":"3","state":"TX","city":"ANDERSON","postal":"77831"},
{"evnCd":"O","rngNum":"4","state":"TX","city":"ANDERSON","postal":"77834"}
]
}
當前在回圈中運行以通過增加 x/y 值來獲得期望的輸出,但性能非常慢,并且迭代需要 8-20 秒,具體取決于檔案的大小以完成拆分程序。當前使用 1.6 版本,是否有任何替代方法可以得到以下結果
預期輸出:陣列中 2 個物件的切片
{"recDt":"2021-01-05","country":"US","name":"ABC","number":"9828","add":[{"rngNum":"1","state":"TX","city":"ANDERSON","postal":"77830"},{"rngNum":"2","state":"TX","city":"ANDERSON","postal":"77832"}]}
{"recDt":"2021-01-05","country":"US","name":"ABC","number":"9828","add":[{"rngNum":"3","state":"TX","city":"ANDERSON","postal":"77831"},{"rngNum":"4","state":"TX","city":"ANDERSON","postal":"77834"}]}
試過了
cat $inFile | jq -cn --stream 'fromstream(1|truncate_stream(inputs))' | jq --arg x $x --arg y $y -c '{recDt: .recDt, country: .country, name: .name, number: .number, add: .add[$x|tonumber:$y|tonumber]}' >> $outFile
cat $inFile | jq --arg x $x --arg y $y -c '{recDt: .recDt, country: .country, name: .name, number: .number, add: .add[$x|tonumber:$y|tonumber]}' >> $outFile
如果有其他可用的,請分享..
uj5u.com熱心網友回復:
在這個只呼叫一次 jq 的回應中,我假設您的計算機有足夠的記憶體來讀取整個 JSON。我還將假設您想要為每個切片創建單獨的檔案,并且您希望 JSON 在每個檔案中都被漂亮地列印出來。
假設塊大小為 2,并且輸出檔案將使用模板 part-N.json 命名,您可以撰寫:
< input.json jq -r --argjson size 2 '
del(.add) as $object
| (.add|_nwise($size) | ("\t", $object {add:.} ))
' | awk '
/^\t/ {fn ; next}
{ print >> "part-" fn ".json"}'
這里使用的技巧是有效的 JSON 不能包含制表符。
uj5u.com熱心網友回復:
以下假設輸入 JSON 太大而無法讀入記憶體,因此使用 jq 的--stream命令列選項。
為了簡單起見,我將專注于.add陣列的“切片” ,而不用擔心其他鍵、漂亮列印和其他細節,因為您可以根據需要輕松調整以下內容:
< input.json jq -nc --stream --argjson size 2 '
def regroup(stream; $n):
foreach (stream, null) as $x ({a:[]};
if $x == null then .emit = .a
elif .a|length == $n then .emit = .a | .a = [$x]
else .emit=null | .a = [$x] end;
select(.emit).emit);
regroup(fromstream( 2 | truncate_stream(inputs | select(.[0][0] == "add")) );
$size)' |
awk '{fn ; print > fn ".json"}'
這會將陣列寫入檔案名格式為 N.json 的檔案
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/407165.html
標籤:
