jq : 命令列json處理工具

Evan
evan.fang
Published in
6 min readSep 30, 2018

jq是一個command line的JSON處理器。

可以在Github查看原始碼,或是參考官方的教學手冊。若是MAC,可以使用以下指令安裝:

brew install jq

使用 jq --version 確認有輸出版本號,代表安裝完成。

以下使用這個網址 https://api.github.com/repos/stedolan/jq/commits?per_page=5,當作json的來源。

curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5'

使用 jq . ,讓jq處理一下:

curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' \
| jq '.'

可以發現,JSON的屬性與值已經能被正確辨識,而不只是單純的字串。

原本的JSON來源,其實是由5個元素所組成的陣列。若只想取出第一個元素,可使用 jq '.[0]'

curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' \
| jq '.[0]'

而若我們只對第一筆資料的commit message以及committer name,這兩個屬性有興趣,希望能從JSON中取出,並組合成如下所示之JSON:

{
message: "commit message of first commit",
name: "name of committer"
}

可以使用如下指令:

curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' \
| jq '.[0] | {message: .commit.message, name: .commit.committer.name}'

若不只是想對第一個元素進行處理,而是想對原本JSON內的5個元素,都取出message與name的話,把 .[0] 的0拿掉即可:

curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' \
| jq '.[] | {message: .commit.message, name: .commit.committer.name}'

但這樣處理的話,是會得到5個元素。若希望這5個元素不是各自分離,而是組成一個陣列的話,則需要使用 []把原來單引號內生產元素的指令包起來,亦即執行以下指令:

curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' \
| jq '[.[] | {message: .commit.message, name: .commit.committer.name}]'

最後,試著取出 parents 的url。

在原本的JSON中,每一個commit可能會有多個 parents ,物件結構可能如下:

// Commit object
{
...
"parents": [
{
"sha": "54b9c9bdb225af5d886466d72f47eafc51acb4f7",
"url": "https://api.github.com/re...",
"html_url": "https://github.com/stedolan/jq/commit/5..."
},
{
"sha": "8b1b503609c161fea4b003a7179b3fbb2dd4345a",
"url": "https://api.github.com/repos/stedolan/jq/commits/...",
"html_url": "https://github.com/stedolan/jq/commit/8b1b5036..."
}
]

我們希望可以取出parents陣列中的 html_url 元素,做出如下的物件:

{
message: "commit message of first commit",
name: "name of committer",
parents: [
"parent url 1",
"parent url 2"
]
}

執行語法如下:

curl 'https://api.github.com/repos/stedolan/jq/commits?per_page=5' \
| jq '[.[] | {message: .commit.message, name: .commit.committer.name, parents: [.parents[].html_url]}]'

其中這段語法

parents: [.parents[].html_url]}]

的意思為:

  1. 我要做出一個parents元素,它會是個陣列。
  2. 陣列的內容是,由當前元素( . 代表當前元素,也就是各個commit元素)的parents陣列內的每個元素的 html_url 所組成。

以上是關於jq的簡介,內容是參考自官方的教學

--

--