在
zq 簡介文 當中我們用 over 來簡單處理 json 檔裡面的一層陣列;
今天我學會處理第二層陣列的方法。
今天的測試資料檔是 「台中市公車的所有路線及所有停靠站」。
如果你有自己的
tdx 服務 的帳號,
可以把下面這段裡面的 「私密目錄」、 「用戶ID」、 「用戶密碼」
及 「都市名稱」 四個地方改成自己合適/想要的值。
如果沒有 tdx 的帳號, 也可以直接下載
我預先抓回來的版本 並解壓縮。
### 如果有自己的 TDX 帳密: ###
export TDX_TOKEN_DIR=$HOME/某個私密目錄
curl -X POST --url https://tdx.transportdata.tw/auth/realms/TDXConnect/protocol/openid-connect/token -H content-type:application/x-www-form-urlencoded -d grant_type=client_credentials -d client_id=uuuuuu-xxxxxxxx-xxxx-xxxx -d client_secret=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx > $TDX_TOKEN_DIR/tdx-credential.json
export TDX_ACCESS_TOKEN=$(jq .access_token $TDX_TOKEN_DIR/tdx-credential.json | sed 's/"//g')
curl -H 'accept: application/json' -H "authorization: Bearer $TDX_ACCESS_TOKEN" "https://tdx.transportdata.tw/api/basic/v2/Bus/DisplayStopOfRoute/City/Taichung" > ~/taichung-bus-rte-stp-stn.json
### 如果沒有自己的 TDX 帳密,就直接下載我備妥的檔案: ###
wget http://fs.cyut.edu.tw/gregslab/22/taichung-bus-rte-stp-stn.json.gz
gunzip taichung-bus-rte-stp-stn.json.gz
首先用
jq 排版檔案:
jq . taichung-bus-rte-stp-stn.json > tcbus.json
並且用文字編輯器打開來研究一下它的結構。
第一層陣列的每個元素代表一條公車路線。
我們有興趣的是 RouteUID (公車路線代號) 這個欄位,
以及 Stops (停靠站牌) 這個欄位。
停靠站牌本身又是一個陣列,
我們只對每個站牌裡面的 StationID (車站代號) 那個欄位有興趣。
RouteUID 跟 StationID 這兩個欄位可以讓我們產生
「路線代號」 與 「車站代號」 的多對多 (many-to-many) 對照表。
第一個簡單的做法是產生每列只有兩個欄位的 csv 檔:
zq -f csv -i json 'over this | over Stops with RouteUID =>
({rte:RouteUID, stn:StationID})' tcbus.json
詳見
zq/zed 手冊 裡面的 "Lateral Subqueries" 那一節。
"with" 後面的一小段用來把外層的欄位名稱 (RouteUID) 帶進來內層使用。
"=>" 後面一定要有小括弧, 括弧裡面就是想要列印的運算式。
第二種做法把同一路線的所有站牌代號全部放在同一列,
前面再加上路線代號:
zq -f csv -i json 'over this |
{ RouteUID, Stations: (over Stops | yield int64(StationID) ) }'
tcbus.json | perl -pe 's/^(\w+),"\[/$1: /; s/\]"$//'
這樣的輸出格式反而比較不方便逆向查詢 (車站代號 => 所有經過路線);
好處是它的列數比較少, 可以算是原始資料的精簡摘要。
總之這篇的重點是要練習語法嘛~
這裡特別注意到第二層的 over 子句並不是接在主要的 pipe 後面,
而是 內嵌 在第一層 over 子句的回傳值的某個欄位裡面,
本身構成了一個陣列。
至於用 int64 做 type cast (型態轉換) 的目的, 是要避免 zq 印出雙引號。
這樣後續要用
regular expressions 處理比較方便。
最終目的是想要做反向查詢的對照表 (車站代號 => 所有經過路線); 透過 StationID 這個欄位抓出經過某個車站的所有路線。 最終決定還是用 python 來寫比較方便。 不過順便學會 zq 的用法, 當然要筆記一下。
沒有留言:
張貼留言
因為垃圾留言太多,現在改為審核後才發佈,請耐心等候一兩天。