command line for JSON
jq
是一個蠻有用、也蠻有趣的 JSON 指令工具。某種程度上來說,我會把他歸類在
Domain-Specifiec Language
,也就是專門操作 JSON 的一個程式語言。最簡單的使用方式就是
jq . [FILE PATH]
來將檔案輸出成一個可讀的 JSON 格式。
透過 -R
的參數 jq 會將讀進來的檔案視為是字串,再透過 filter 處理變成相對的 JSON 內容。
而 -s
參數會將獨進來的內容視為是一個完整的 JSON 內容而非每一行處理。
Filter
jq 支援各種直覺的 filter 來操作各種 JSON 資料型態。.
可以用來代表當下的資料,而 .[]
則是代表將當下資料視為 array 來列舉:進階的使用 .[]?
則可以列舉所有內容、但如果出現不合法內容,
則不會噴錯且繼續執行。針對 array 也支援各種物件存取.[1]
與 sub-array 的操作.[0:-3]
。
這種操作也可以對字串 (string) 操作而得到預期般的結果。
如果操作的是物件本身,則可以透過.attr
來存取物件 key 為 attr 的值 (value):透過.attr?
來存取則可以避免當物件沒有 attr 這個 key 時會噴錯。
Pipe
當需要將 JSON 物件做複雜的操作時 Pipe |
是一個很常使用的技巧。像是需要存取物件的階層關係時,
可以使用 .a | .b | .c
來使用。這個語法等價於 .a.b.c
,而接下來的很多技巧都會使用到 pipe。
map
map
與 map_value
都屬於 jq 的
語法糖 (syntax sugar)
。map 是用來列舉每個 array 的元素,
並且針對每個元素作操作。map(x)
的語法等價於 [ .[] | x ]
同理 map_value(x)
等價於
.[] |= x
。
reduce
reduce
跟 map
語法類似,都是對 array 物件依序做處理,然而 reduce 語法則是將上一次執行的結果,
當作是參數的一部分。像是 reduce .[] as $item (0; . + $item)
則是將 array 的內容依序加起來,
而起始內容則為是 0
。
Example
進階的例子則是將
CSV
檔案轉換成 JSON 的形式:執行指令 jq -Rcs '. / "\n" | map( . / "," )'
就可以將 CSV (用 , 做分隔) 的檔案轉換成 JSON 形式。