我有一個 POSIX 相容的安裝腳本,它透過從軟體註冊表檢索的 json blob 中 grep 資訊來確定某些軟體的最新版本:
meta=$(wget -qO - https://registry.npmjs.org/after-dark/latest)
grep --version | grep "BSD grep" 1>/dev/null && vers=$(echo "$meta" | grep -oE '"version":(\d*?,|.*?[^\\]",)' | tr -d 'version": ,')
grep --version | grep "GNU grep" 1>/dev/null && vers=$(echo "$meta" | grep -oP '"version":(\d*?,|.*?[^\\]",)' | tr -d 'version": ,')
我需要使該軟體與 BusyBox 相容,BusyBox 與 BSD grep 一樣,-E
用於擴展正規表示式支援。但是,它不支援--version
標誌。
如果我運行busybox grep
我會看到 busybox 的版本。我應該用它來增加相容性嗎?有沒有更好的方法可以在不安裝依賴項的情況下消除程式碼氣味。
答案1
等不及了,所以我對此進行了一些新的關注,並提出了以下解決方案,該解決方案使用 GNU、BSD 和 BusyBox grep 進行了良好的測試,並改進了對 semver 的支援:
egrep -o "\"version\".*[^,]*," <<< "$meta" | cut -d ',' -f1 | cut -d ':' -f2 | tr -d '" '
它的工作原理是呼叫 ERE grep正規表示式(有一個帽尖) 並用於cut
切掉尾隨的逗號,抓取 右側的所有內容:
,修剪字串並刪除所有存在的雙引號。
給$meta
定 的{"version":"5.5.0-beta4",}
將準確返回5.5.0-beta4
。
給$meta
定 的"version" : 1,
將準確返回1
。
假設version
field 不是 JSON blob 中的最後一個字段,這是可讀性的權衡。
應用於原始問題的結果是:
vers=$(echo "$meta" | egrep -o "\"version\".*[^,]*," | cut -d ',' -f1 | cut -d ':' -f2 | tr -d '" ')
無需偵測 grep 版本並消除程式碼異味。
更新: