昨天我們認識了 jq 的變數,應用在方向的顯示資訊對應上,比起使用 if-then-else-end,使用變數對應取值是更俐落的做法。只是,方向的資料雖然不多、卻也不短,直接把 json 放在主程式內,還是嫌稍長了。我們今天就來看看,jq 的 slurp 可以怎麼幫上忙吧。
徒弟:把整個 $direction 的 json 寫在程式中看起來太冗長了,有沒有存在一個 direction.json 檔案中的辦法?
師傅:很好的問題。我們今天就來學習如何從外部文件讀取多個 JSON 資料。
徒弟:太好了!這樣可以讓程式更整潔吧?
師傅:沒錯。首先,我們要了解 jq 的 -s
或 --slurp
選項。
徒弟:這是什麼意思呢,師傅?
師傅:-s
選項將多個輸入合併為一個陣列。它讀取整個輸入串流,並將其作為單個陣列傳遞給 jq。
徒弟:哦,這聽起來很有用。可以舉個例子嗎?
師傅:當然。看這個:
jq -s '.' file1.json file2.json
師傅:這會將 file1.json 和 file2.json 的內容合併為一個陣列。
徒弟:我明白了。那麼,我們如何用這個來讀取 direction.json 呢?
師傅:首先,我們準備好 direction.json 文件。內容如下:
{
"N": "北 ↑", "S": "南 ↓", "E": "東 →", "W": "西 ←",
"NE": "東北 ↗", "SE": "東南 ↘", "SW": "西南 ↙", "NW": "西北 ↖"
}
徒弟:好的,我已經建立了這個文件。接下來呢?
師傅:現在,我們使用 jq 讀取這個文件並將其儲存為變數。
jq -s '.[0] as $direction | $direction' direction.json
徒弟:這行命令看起來有點複雜,能解釋一下嗎?
師傅:當然。-s 選項將文件內容讀取為陣列,.[0] 取第一個元素,然後我們將其賦值給 $direction 變數。
徒弟:明白了。那麼,接著作法就跟先前一樣 $direction[.movingDirection]
對嗎?
師傅:沒錯。使用 slurp 就可以讓資料存在獨立的 json 檔案,不用全部寫在 jq 程式中了,提高了可維護姓。
徒弟:謝謝師傅。我會好好練習這個技巧的。
-s
或 --slurp
選項用於將多個輸入視為單個大陣列。它會讀取整個輸入串流,並將其作為一個陣列傳遞給 jq 程式。這在處理多個 JSON 對象或需要將多個輸入合併為一個陣列時非常有用。
我們先將山陀兒颱風的資料下載為 typhoon1005.json,如下:
curl -s https://opendata.cwa.gov.tw/api/v1/rest/datastore/W-C0034-005?Authorization=%AUTHORIZATION% > typhoon1005.json
再如對話中所說,準備 direction.json,這樣我們就有兩個 json 檔案。接著,使用 jq -s
讀取 direction.json 和 typhoon1005.json。我們已經知道讀取的結果是一個大的陣列,而陣列的第一個元素會是 direction.json 的內容,第二個元素則會是 typhoon1005.json 的內容。
因此我們可以如下方式,命名陣列的第一個元素為 $direction,第二個元素為 $ty。
jq -s ".[0] as $direction | .[1] as $ty | $direction[\"N\"], ($ty | .records.tropicalCyclones.tropicalCyclone[] | .typhoonName)" direction.json typhoon1005.json
執行此指令的結果是:
"北 ↑"
"KRATHON"
由此可知,只要應用 $direction 和 $ty 這兩個變數,就可以套用先前的程式碼了 🎉
按照這個做法,修改昨天的程式碼如下,跑起來的結果會跟昨天一樣:
jq -c -r -s ".[0] as $direction | .[1] as $ty |[\"時間 \",\"經度\",\"緯度\",\"氣壓\",\"風速MAX\",\"陣風MAX\",\"方向 \",\"預測\"],[$ty.records.tropicalCyclones.tropicalCyclone[] | select(.typhoonName==\"KRATHON\") | .analysisData.fix[-5:][] | [.fixTime[0:13], (.coordinate|split(\",\")[0]), (.coordinate|split(\",\")[1]), .pressure, .maxWindSpeed, .maxGustSpeed, $direction[.movingDirection], .movingPrediction[0].value]][] | @tsv" direction.json typhoon1005.json
今天真正見識了 jq -s
拿來應用的好處:同時處理多個 json ,整併為一個陣列,使用索引取得元素內容,並儲存於變數,後面的運用就如同我們先前學到的各種方法。今天的修改可以參考 程式碼。
💡想一想,如果風速的分級也能另存為一個 json,這樣又可以再讀入分級的資訊,將颱風的最大風速對應成"幾級風"來顯示,聽起來很不錯! 可以是明天的練習 😁
感謝自己今天也認真的練習。感謝大家互相幫忙,整理收拾山陀兒颱風留下的一地樹枝和各種砸落的看板 ❤️