antony@notes:~/misc$ cat "jq-命令.md"
jq 命令
jq 命令
好的,讓我們詳細解釋以下這個命令的作用和每個部分的功能:
skopeo list-tags docker://docker.io/rancher/k3s | jq -r '
[.Tags[] | select(test("^v1\\.[0-9]+\\.[0-9]+-k3s1$"))]
| group_by(split(".")[1])
| map(max_by(split(".")[2] | split("-")[0] | tonumber))
| .[]
'整體概述
這個命令的主要目的:
- 使用 skopeo 工具列出 Docker 映像
rancher/k3s的所有標籤(tags)。 - 使用
jq來處理輸出的 JSON 數據,篩選出符合特定版本格式的標籤。 - 根據次要版本號(
v1.x)對標籤進行分組。 - 在每個次要版本組中,選出修訂版本號(
v1.x.y中的y)最大的標籤,即每個次要版本的最新版本。 - 最終,輸出每個次要版本的最新標籤,並以純文本形式顯示。
逐步解釋
1. 列出 Docker 映像的所有標籤
skopeo list-tags docker://docker.io/rancher/k3sskopeo:一個用於處理 Container Images 的工具,可以在不下載整個映像的情況下檢查遠程 Container Images 的內容。list-tags docker://docker.io/rancher/k3s:列出docker.io/rancher/k3s的所有 Tags。
執行此命令後,會得到一個包含所有標籤的 JSON 格式輸出,類似於:
{
"Repository": "docker.io/rancher/k3s",
"Tags": [
"v1.16.15-k3s1",
"v1.17.17-k3s1",
"v1.18.20-k3s1",
"v1.19.16-k3s1",
"v1.20.15-k3s1",
...
]
}2. 將輸出傳遞給 jq 進行處理
| jq -r '
[ ... ]
| group_by(...)
| map(...)
| .[]
'|:將前一個命令的輸出作為下一個命令的輸入。jq -r:jq是一個用於處理 JSON 的命令行工具。-r:表示輸出原始文本(raw output),不包含引號和轉義字符。
3. 篩選符合特定格式的標籤
[.Tags[] | select(test("^v1\\.[0-9]+\\.[0-9]+-k3s1$"))].Tags[]:從 JSON 數據中提取Tags陣列,並展開為單個元素。| select(test("...")):使用正則表達式篩選符合特定格式的標籤。test("^v1\\.[0-9]+\\.[0-9]+-k3s1$"):^:表示字符串的開頭。v1\\.:匹配字面量v1.,注意在正則表達式中,.需要轉義,因此寫作\\.。[0-9]+:匹配一個或多個數字。\\.:匹配字面量.。[0-9]+:再次匹配一個或多個數字。-k3s1$:匹配字面量-k3s1,$表示字符串的結尾。
- 整體作用:選取形如
v1.<次要版本號>.<修訂版本號>-k3s1的標籤,例如v1.29.8-k3s1。
[ ... ]:將篩選後的標籤組成一個新的陣列,方便後續處理。
篩選結果示例:
[
"v1.29.7-k3s1",
"v1.29.8-k3s1",
"v1.30.0-k3s1",
"v1.30.1-k3s1",
"v1.30.2-k3s1",
"v1.30.3-k3s1",
"v1.30.4-k3s1",
"v1.31.0-k3s1"
]4. 根據次要版本號分組
| group_by(split(".")[1])split("."):將每個標籤按.分割,得到一個陣列。- 例如,
v1.29.8-k3s1會被分割為["v1", "29", "8-k3s1"]。
- 例如,
[1]:取陣列的第二個元素(索引從 0 開始),即次要版本號。- 在上述例子中,
split(".")[1]得到"29"。
- 在上述例子中,
group_by(...):根據次要版本號對標籤進行分組。- 所有具有相同次要版本號的標籤將被分為一組。
分組結果示例:
[
[
"v1.29.7-k3s1",
"v1.29.8-k3s1"
],
[
"v1.30.0-k3s1",
"v1.30.1-k3s1",
"v1.30.2-k3s1",
"v1.30.3-k3s1",
"v1.30.4-k3s1"
],
[
"v1.31.0-k3s1"
]
]5. 在每個分組中選取修訂版本號最大的標籤
| map(max_by(split(".")[2] | split("-")[0] | tonumber))map(...):對陣列中的每個元素(這裡是每個分組)應用一個函數,返回一個新陣列。max_by(...):在分組中根據指定的鍵選取最大值。split(".")[2]:將標籤按.分割,取得第三個元素,即修訂版本號和後綴。- 例如,
v1.29.8-k3s1變為["v1", "29", "8-k3s1"],取split(".")[2]得到"8-k3s1"。
- 例如,
split("-")[0]:將上一步的結果按-分割,取得修訂版本號。"8-k3s1"分割後得到["8", "k3s1"],取[0]得到"8"。
tonumber:將字符串轉換為數字,以便進行數值比較。- 整體作用:在每個次要版本號的分組中,選出修訂版本號(
y)最大的標籤。
選取結果示例:
[
"v1.29.8-k3s1",
"v1.30.4-k3s1",
"v1.31.0-k3s1"
]6. 展開陣列並輸出結果
| .[].[]:遍歷陣列中的每個元素,將其單獨輸出。- 由於使用了
-r選項,輸出將是純文本格式,不包含引號或其他符號。
最終輸出:
v1.29.8-k3s1
v1.30.4-k3s1
v1.31.0-k3s1總結
- 步驟 1:使用
skopeo列出rancher/k3s映像的所有標籤。 - 步驟 2:使用
jq篩選出符合v1.x.y-k3s1格式的標籤。 - 步驟 3:根據次要版本號(
x)對標籤進行分組。 - 步驟 4:在每個分組中,選出修訂版本號(
y)最大的標籤。 - 步驟 5:輸出每個次要版本的最新標籤,結果為純文本格式。
為什麼要這樣做?
- 自動獲取最新版本:這個命令可以自動獲取每個次要版本的最新可用版本,方便進行部署或升級。
- 過濾無效或不需要的標籤:通過正則表達式篩選,只保留符合預期格式的標籤,避免處理測試版、候選版或其他不符合標準的標籤。
- 簡化後續處理:輸出為純文本格式,每個標籤佔一行,方便在腳本或其他工具中進行處理。
相關函數和語法解釋
test("正則表達式")
- 作用:檢查字符串是否匹配指定的正則表達式,返回布爾值。
- 示例:
test("^v1\\.[0-9]+\\.[0-9]+-k3s1$")檢查字符串是否符合版本格式。
split("分隔符")
- 作用:將字符串按指定的分隔符分割為陣列。
- 示例:
"v1.29.8-k3s1" | split(".")會得到["v1", "29", "8-k3s1"]。
group_by(鍵)
- 作用:根據指定的鍵對陣列進行分組,返回一個包含多個子陣列的陣列。
- 示例:
group_by(split(".")[1])根據次要版本號對標籤進行分組。
map(函數)
- 作用:對陣列中的每個元素應用指定的函數,返回一個新陣列。
- 示例:
map(max_by(...))對每個分組選取最大值。
max_by(鍵)
- 作用:在陣列中根據指定的鍵選取最大值的元素。
- 示例:
max_by(split(".")[2] | split("-")[0] | tonumber)根據修訂版本號選取最大值。
tonumber
- 作用:將字符串轉換為數字。
- 示例:
"8" | tonumber轉換為數字8。
.[]
- 作用:遍歷陣列中的每個元素,將其單獨輸出。
- 示例:
["a", "b", "c"] | .[]會輸出a、b、c。
實際應用示例
假設您需要在自動化部署腳本中,獲取 rancher/k3s 映像的每個次要版本的最新版本,可以使用此命令自動獲取,避免手動查詢和更新。
注意事項
- 網絡連接:需要能夠訪問
docker.io的網絡連接,以獲取映像標籤信息。 - 正則表達式:確保正則表達式與您需要的版本格式匹配,必要時可以調整。
總結
這個命令結合了 skopeo 和 jq 的功能,自動化地從 Docker 映像庫中獲取特定格式的標籤,並選取每個次要版本的最新修訂版本,對於需要保持軟體版本更新的情況非常實用。
如果您對某些部分仍有疑問,或者需要進一步的解釋,請隨時告訴我!