Skip to content

antony@notes:~/misc$ cat "jq-命令.md"

jq 命令

2024-09-15· misc

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/k3s
  • skopeo:一個用於處理 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 -rjq 是一個用於處理 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"] | .[] 會輸出 abc

實際應用示例

假設您需要在自動化部署腳本中,獲取 rancher/k3s 映像的每個次要版本的最新版本,可以使用此命令自動獲取,避免手動查詢和更新。


注意事項

  • 網絡連接:需要能夠訪問 docker.io 的網絡連接,以獲取映像標籤信息。
  • 正則表達式:確保正則表達式與您需要的版本格式匹配,必要時可以調整。

總結

這個命令結合了 skopeojq 的功能,自動化地從 Docker 映像庫中獲取特定格式的標籤,並選取每個次要版本的最新修訂版本,對於需要保持軟體版本更新的情況非常實用。

如果您對某些部分仍有疑問,或者需要進一步的解釋,請隨時告訴我!