2016-08-30 36 views
1

我從curl得到一個非常大的JSON流(幾GB),並嘗試用jq來處理它。用jq處理大型JSON流

相關輸出我想與jq解析填充表示結果結構文檔中:

{ 
    "results":[ 
    { 
     "columns": ["n"], 

     // get this 
     "data": [  
     {"row": [{"key1": "row1", "key2": "row1"}], "meta": [{"key": "value"}]}, 
     {"row": [{"key1": "row2", "key2": "row2"}], "meta": [{"key": "value"}]} 
     // ... millions of rows  

     ] 
    } 
    ], 
    "errors": [] 
} 

我想與jq提取row數據。這是簡單的:

curl XYZ | jq -r -c '.results[0].data[0].row[]' 

結果:

{"key1": "row1", "key2": "row1"} 
{"key1": "row2", "key2": "row2"} 

然而,這總是等待curl完成。

我玩--stream選項,這是用來處理這個。我想下面的命令,但也一直等待,直到完整的對象從curl返回:

curl XYZ | jq -n --stream 'fromstream(1|truncate_stream(inputs)) | .[].data[].row[]' 

有沒有一種方法來「跳」到data領域,並開始解析row一個接一個,而不必等待關閉標籤?

回答

2

(1)你會使用將作爲香草過濾如下:

jq -r -c '.results[0].data[].row' 

(2)使用流解析器這裏將用它來處理的.results[0].data輸出的一種方式,但這兩個步驟的組合可能會比香草方法慢。

(3)你不妨沿着這些線路試一下:

jq -n --stream 'inputs 
     | select(length==2) 
     | select([.[0][0,2,4]] == ["results", "data", "row"]) 
     | [ .[0][6], .[1]] ' 

爲了說明輸入(修改,使其有效的JSON),輸出將是:

[ "key", "value1" ] [ "key", "value2" ]

+0

這不僅是速度。沒有流內存使用爆炸和curl/jq崩潰。 –

+0

謝謝,你的更新確實幫了很大忙。我並沒有真正到達那裏,因爲所有的行都被組合在輸出中。我還沒有想出如何收集各行的所有鍵/值對。我更新了問題中的數據描述。 –

+0

我所要做的就是將'。[0] [3]'等於一個對象的所有數組。 –

0

要獲取:

{"key1": "row1", "key2": "row1"} {"key1": "row2", "key2": "row2"}

來源:

{ "results":[ { "columns": ["n"], "data": [
{"row": [{"key1": "row1", "key2": "row1"}], "meta": [{"key": "value"}]}, {"row": [{"key1": "row2", "key2": "row2"}], "meta": [{"key": "value"}]} ] } ], "errors": [] }

執行以下,這相當於jq -c '.results[].data[].row[]',但使用流:

​​

這樣做是:

  • 打開JSON成流(與--stream
  • 選擇路徑.results[].data[].row[](與select(.[0][0] == "results" and .[0][2] == "data" and .[0][4] == "row"
  • 丟棄的路徑的那些最初的部分,如"results",0,"data",0,"row"(與del(.[0][0:5])
  • 最後從jq FAQ
  • 轉動所得JQ流返回到預期的JSON與 fromstream(1|truncate_stream(…))圖案

例如:

echo '{"results":[{"columns":["n"],"data":[{"row":[{"key1":"row1","key2":"row1"}],"meta":[{"key":"value"}]},{"row":[{"key1":"row2","key2":"row2"}],"meta":[{"key":"value"}]}]}],"errors":[]}' | jq -cn --stream 'fromstream(1|truncate_stream(inputs | select(.[0][0] == "results" and .[0][2] == "data" and .[0][4] == "row") | del(.[0][0:5])))'

可生產的期望的輸出。