Bash
使用 jq 重新格式化 json
我有以下 JSON 文件:
{ data : [ { "name" : "name1" "date" : [ { "date1" : "aaa", "date2" : "bbb" }, { "date1" : "ccc", "date2" : "ddd" }, { "date1" : "eee", "date2" : "fff" }, "var" : "ggg" }, { "name" : "name2" "date" : [ { "date1" : "hhh", "date2" : "iii" }, { "date1" : "jjj", "date2" : "kkk" }, "var" : "lll" } ] }
我想要這種格式的 CSV 文件:
name, date, var name1, aaa ccc eee, ggg name2, hhh jjj, lll
僅使用jq可以做到這一點嗎?
假設您的 JSON 文件格式正確,例如您呈現的文本的以下修改變體:
{ "data": [ { "name": "name1", "date": [ { "date1": "aaa", "date2": "bbb" }, { "date1": "ccc", "date2": "ddd" }, { "date1": "eee", "date2": "fff" } ], "var": "ggg" }, { "name": "name2", "date": [ { "date1": "hhh", "date2": "iii" }, { "date1": "jjj", "date2": "kkk" } ], "var": "lll" } ] }
然後我們可以執行以下操作:
$ jq -r '[ "name", "date", "var" ], (.data[] | [.name, ([.date[].date1] | join(" ")), .var]) | @csv' file "name","date","var" "name1","aaa ccc eee","ggg" "name2","hhh jjj","lll"
jq
表達式,用更多的空氣來顯示結構:[ "name", "date", "var" ], ( .data[] | [ .name, ( [ .date[].date1 ] | join(" ") ), .var ] ) | @csv
這首先將 CSV 標頭創建為字元串數組。然後它遍歷頂層
data
數組,將name
和var
鍵的值提取到一個數組中。它還挑選出數組date1
中子鍵的所有值date
,並將它們與空格連接起來作為分隔符。然後使用 CSV 標頭數組以及為每個
data
元素構造的數組進行處理以輸出@csv
,它引用每個字元串並用逗號分隔元素。另一種變體:
box% jq -r '.data[].date |= ( [.[].date1] | join(" ") ) | [ (.data[0] | keys[]) ], (.data[]| [.[]]) | @csv' file "date","name","var" "name1","aaa ccc eee","ggg" "name2","hhh jjj","lll"
這會預處理數據,以便第一個管道之後的表達式部分獲得以下輸入:
{ "data": [ { "name": "name1", "date": "aaa ccc eee", "var": "ggg" }, { "name": "name2", "date": "hhh jjj", "var": "lll" } ] }
第一個管道之後的程式碼只需提取 CSV 標頭的鍵,然後收集值,而不必擔心鍵的名稱。
再一次,
jq
為了說明而插入了一點 mor 空氣的表達式:.data[].date |= ( [ .[].date1 ] | join(" ") ) | [ (.data[0] | keys[]) ], ( .data[] | [.[]] ) | @csv
時髦的外觀
.data[] | [.[]]
創建了每個元素中所有鍵的值的數組data
。如果擔心
.[]
應用於非數組可能會以與keys
產生的順序不同的順序提取值,那麼可以使用.data[].date |= ( [ .[].date1 ] | join(" ")) | (.data[0] | keys) as $keys | $keys, ( .data[]| [ .[$keys[]] ] ) | @csv
即,將標題鍵提取到變數
$keys
中,使用它來創建 CSV 標題並data
從數組中的元素中提取數據。列可能是隨機順序,但至少標題和其餘數據是相同的隨機順序,CSV 解析器按名稱提取列沒有問題。