如何使用 JMESPath 查詢來查詢 Azure CLI 命令輸出

Azure CLI 會使用 --query 參數,在命令結果上執行 JMESPath 查詢 。 JMESPath 是 JSON 的查詢語言,可讓您從 CLI 輸出中選取和修改數據。

Azure CLI 中的所有命令都支持 --query 參數。 本文說明如何使用 JMESPath 的功能,並提供查詢範例。 瞭解 JMESPath 概念,這些概念適用於在 [概念] 索引標籤下查詢。請參閱 [範例] 索引卷標底下的 JMESPath 查詢範例。

Azure CLI 會使用查詢來選取和修改 Azure CLI 命令的輸出。 查詢會在 Azure CLI 命令的傳回 JSON 物件上執行用戶端,再進行任何顯示格式設定。

查詢中所需的逸出字元會因不同環境而有所不同。 建議您在 Azure Cloud Shell 或 Cmd 中執行查詢,因為這些殼層需要較少的逸出字元。 若要確保查詢範例語法正確,請選取您所使用的殼層索引標籤。

字典和清單 CLI 結果

CLI 命令結果會先視為查詢的 JSON,即使輸出格式不是 JSON。 CLI 結果為 JSON 陣列或字典。 陣列是可編制索引的物件序列,而字典是使用索引鍵存取的未排序物件。

這是陣列的範例:

[ 
  1,
  2,
  3
]

這是字典的範例:

{
  "isRunning": false,
  "time": "12:00",
  "number": 1
}

可以傳回多個物件的命令會傳回數位,而且一律只傳回單一物件的命令傳回字典。

取得字典中的屬性

使用字典結果時,您可以只使用 索引鍵從最上層存取屬性。 .subexpression) 字元可用來存取巢狀字典的屬性。 在引進查詢之前,請先看看 az vm show 命令的未修改輸出:

az vm show --resource-group QueryDemo --name TestVM

命令會輸出字典。 部分內容已省略。

{
  "additionalCapabilities": null,
  "availabilitySet": null,
  "diagnosticsProfile": {
    "bootDiagnostics": {
      "enabled": true,
      "storageUri": "https://xxxxxx.blob.core.windows.net/"
    }
  },
  ...
  "osProfile": {
    "adminPassword": null,
    "adminUsername": "azureuser",
    "allowExtensionOperations": true,
    "computerName": "TestVM",
    "customData": null,
    "linuxConfiguration": {
      "disablePasswordAuthentication": true,
      "provisionVmAgent": true,
      "ssh": {
        "publicKeys": [
          {
            "keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso",
            "path": "/home/azureuser/.ssh/authorized_keys"
          }
        ]
      }
    },
    "secrets": [],
    "windowsConfiguration": null
  },
  ....
}

下列命令會藉由新增查詢,取得已授權連線到 VM 的 SSH 公鑰:

az vm show --resource-group QueryDemo --name TestVM --query "osProfile.linuxConfiguration.ssh.publicKeys"
[
  {
    "keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso",
    "path": "/home/azureuser/.ssh/authorized_keys"
  }
]

查詢字串會區分大小寫。 例如,將 'osProfile' 變更為上一個查詢中的 'OsProfile' 不會傳回正確的結果。

取得多個值

若要取得多個屬性,請將以逗號分隔的表達式放在方括弧 [ ] 中( 多重選取清單)。 下列命令會取得 VM 名稱、系統管理員使用者和 SSH 金鑰:

az vm show --resource-group QueryDemo --name TestVM --query "[name, osProfile.adminUsername, osProfile.linuxConfiguration.ssh.publicKeys[0].keyData]"
[
  "TestVM",
  "azureuser",
  "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso"
]

這些值會以查詢中提供的順序列在結果陣列中。 由於結果是陣列,因此沒有與結果相關聯的索引鍵。 若要取得字典而非陣列,請參閱下一節。

重新命名查詢中的屬性

若要在查詢多個值時取得字典,而不是陣列,請使用 { }multiselect hash) 運算符。 多重選取哈希的格式為 {displayName:JMESPathExpression, ...}displayName 是輸出中顯示的字串,而 JMESPathExpression 是要評估的 JMESPath 表達式。 將多重選取清單變更為哈希,以修改最後一節的範例:

注意

如果您選擇在新的數據行名稱中使用空格,例如 VM nameVMName而不是 ,Bash 和 PowerShell 中的引用規則都會變更。 如需範例,請參閱 在 Azure CLI 參數 中傳遞空格。

az vm show --resource-group QueryDemo --name TestVM --query "{VMName:name, admin:osProfile.adminUsername, sshKey:osProfile.linuxConfiguration.ssh.publicKeys[0].keyData}"
{
  "VMName": "TestVM",
  "admin": "azureuser",
  "ssh-key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso"
}

取得陣列中的屬性

數位上沒有本身的屬性,但可以編制索引。 這個功能會顯示在最後一個範例中,表達式 publicKeys[0],其會取得陣列的第一個專案 publicKeys 。 不保證 CLI 輸出已排序,因此除非您確定順序或不在乎取得的項目,否則請避免使用索引編製。 若要存取陣列中元素的屬性,您可以執行兩項作業之一: 扁平化篩選。 本節說明如何扁平化陣列。

使用 JMESPath 運算符來 [] 壓平陣列。 運算子之後 [] 的所有表達式都會套用至目前陣列中的每個專案。 如果在 [] 查詢開頭出現,它會平整 CLI 命令結果。 您可以使用這項功能來檢查 的結果 az vm list 。 下列查詢會取得資源群組中每個 VM 的名稱、OS 和系統管理員名稱:

az vm list --resource-group QueryDemo --query "[].{Name:name, OS:storageProfile.osDisk.osType, admin:osProfile.adminUsername}"
[
  {
    "Name": "Test-2",
    "OS": "Linux",
    "admin": "sttramer"
  },
  {
    "Name": "TestVM",
    "OS": "Linux",
    "admin": "azureuser"
  },
  {
    "Name": "WinTest",
    "OS": "Windows",
    "admin": "winadmin"
  }
]

任何陣列都可以扁平化,而不只是命令所傳回的最上層結果。 在最後一節中,表達式 osProfile.linuxConfiguration.ssh.publicKeys[0].keyData 是用來取得 SSH 公鑰以進行登入。 若要取得 每個 SSH 公鑰,表示式可以改為撰寫為 osProfile.linuxConfiguration.ssh.publicKeys[].keyData。 此查詢表示式會 osProfile.linuxConfiguration.ssh.publicKeys 扁平化數位,然後在每個元素上執行 keyData 表示式:

az vm show --resource-group QueryDemo --name TestVM --query "{VMName:name, admin:osProfile.adminUsername, sshKeys:osProfile.linuxConfiguration.ssh.publicKeys[].keyData }"
{
  "VMName": "TestVM",
  "admin": "azureuser",
  "sshKeys": [
    "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMobZNJTqgjWn/IB5xlilvE4Y+BMYpqkDnGRUcA0g9BYPgrGSQquCES37v2e3JmpfDPHFsaR+CPKlVr2GoVJMMHeRcMJhj50ZWq0hAnkJBhlZVWy8S7dwdGAqPyPmWM2iJDCVMVrLITAJCno47O4Ees7RCH6ku7kU86b1NOanvrNwqTHr14wtnLhgZ0gQ5GV1oLWvMEVg1YFMIgPRkTsSQKWCG5lLqQ45aU/4NMJoUxGyJTL9i8YxMavaB1Z2npfTQDQo9+womZ7SXzHaIWC858gWNl9e5UFyHDnTEDc14hKkf1CqnGJVcCJkmSfmrrHk/CkmF0ZT3whTHO1DhJTtV stramer@contoso\n"
  ]
}

使用布爾表達式篩選陣列

用來從陣列取得數據的另一項作業是 篩選。 篩選是使用 [?...] JMESPath 運算子完成的。 這個運算符會採用述詞作為其內容。 述詞是任何可評估為 truefalse的語句(包括布爾屬性)。 述詞評估為 true 的表示式會包含在輸出中。

第一個查詢示範如何列出連線至您帳戶的所有 Azure 訂用帳戶名稱,其 isDefault 屬性為 true。 第二個和第三個查詢會顯示兩種不同的方式,列出屬性 isDefault 為 false 的所有訂用帳戶。

# Boolean values are assumed to be true, so you can directly evaluate the isDefault property to return the default subscription.
az account list --query "[?isDefault].name"

# To check if a Boolean property is false, you can use the comparison operator == or the logical operator !.
az account list --query '[?!isDefault].name'
az account list --query "[?isDefault == \`false\`].name"

JMESPath 提供標準比較和邏輯運算符。 這些包括 <<=>>===、 和 !=。 JMESPath 也支援邏輯和 (&&), 或 (||), 而不是 (!)。 表達式可以分組在括弧內,以允許更複雜的述詞表達式。 如需述詞和邏輯作業的完整詳細數據,請參閱 JMESPath 規格

在最後一節中,您已扁平化陣列,以取得資源群組中所有 VM 的完整清單。 使用篩選條件時,此輸出只能限制為Linux VM:

az vm list --resource-group QueryDemo --query "[?storageProfile.osDisk.osType=='Linux'].{Name:name,  admin:osProfile.adminUsername}" --output table
Name    Admin
------  ---------
Test-2  sttramer
TestVM  azureuser

您也可以篩選數值,例如 OS 磁碟大小。 下列範例示範如何篩選 VM 清單,以顯示磁碟大小大於或等於 50 GB 的 VM 清單。

az vm list --resource-group QueryDemo --query "[?storageProfile.osDisk.diskSizeGb >=\`50\`].{Name:name,  admin:osProfile.adminUsername, DiskSize:storageProfile.osDisk.diskSizeGb }" --output table
Name     Admin     DiskSize
-------  --------  --------
WinTest  winadmin  127

對於大型陣列,在選取數據之前套用篩選可能會比較快。

重要

在 JMESPath 中,字串一律會以單引號 (') 或逸出字元 (`) 括住。 如果您在篩選述詞中使用雙引號做為字串的一部分,您將會收到空的輸出。

JMESPath 函式

JMESPath 也有內建函式,可允許更複雜的查詢和修改查詢輸出。 本節著重於使用 JMESPath 函式來建立查詢,而 使用函 式操作輸出一節示範如何使用函式來修改輸出。

在呼叫函式之前會評估表達式,因此自變數本身可以是 JMESPath 表達式。 下列範例會使用 contains(string, substring)來示範這個概念,它會檢查字串是否包含子字串。 這個指令會尋找針對其 OS 磁碟使用 SSD 記憶體的所有 VM:

az vm list --resource-group QueryDemo --query "[?contains(storageProfile.osDisk.managedDisk.storageAccountType,'SSD')].{Name:name, Storage:storageProfile.osDisk.managedDisk.storageAccountType}"
[
  {
    "Name": "TestVM",
    "Storage": "StandardSSD_LRS"
  },
  {
    "Name": "WinTest",
    "Storage": "StandardSSD_LRS"
  }
]

管道表達式

類似於 | 命令行中的使用方式, | 可以在 JMESPath 查詢中使用,將表示式套用至中繼查詢結果。 我們也可以使用 | 將複雜的查詢分解成更簡單的子表達式。 若要縮短上一節的查詢,請使用 | 在壓平並選取數據之後套用篩選。

az vm list --resource-group QueryDemo --query "[].{Name:name, Storage:storageProfile.osDisk.managedDisk.storageAccountType} | [? contains(Storage,'SSD')]"
[
  {
    "Name": "TestVM",
    "Storage": "StandardSSD_LRS"
  },
  {
    "Name": "WinTest",
    "Storage": "StandardSSD_LRS"
  }
]

如需函式的完整清單,請參閱 JMESPath 規格 - 內建函式。

使用函式操作輸出

JMESPath 函式也有另一個用途,也就是在查詢的結果上運作。 傳回非布爾值的任何函式會變更表達式的結果。 例如,您可以使用 來依 屬性值 sort_by(array, &sort_expression)排序數據。 JMESPath 會針對稍後應評估為函式一部分的運算式使用特殊運算子 &。 下一個範例示範如何依 OS 磁碟大小排序 VM 清單:

az vm list --resource-group QueryDemo --query "sort_by([].{Name:name, Size:storageProfile.osDisk.diskSizeGb}, &Size)" --output table
Name     Size
-------  ------
Test-2   30
TestVM   32
WinTest  127

如需函式的完整清單,請參閱 JMESPath 規格 - 內建函式。

格式化查詢結果

Azure CLI 會使用 JSON 作為其預設輸出格式,但不同的輸出格式可能會根據查詢的目的和結果而更適合查詢。 查詢一律會先在 JSON 輸出上執行,然後格式化。

本節將會進行 tsvtable 格式化,以及每個格式的一些使用案例。 如需輸出格式的詳細資訊,請參閱 Azure CLI 命令的輸出格式。

TSV 輸出格式

輸出格式會 tsv 傳回索引標籤和換行符分隔的值,而不需要額外的格式、索引鍵或其他符號。 當輸出儲存在參數中,並用於另一個命令時,這個格式很有用。

格式化的 tsv 其中一個使用案例是從 CLI 命令擷取值,例如 Azure 資源識別碼或資源名稱,並將值儲存在本機環境變數中。 根據預設,結果會以 JSON 格式傳回,在處理以字元括住 " 的 JSON 字串時,這可能是個問題。 如果命令輸出直接指派給環境變數,殼層可能無法解譯引號。 在下列範例中,將查詢結果指派給環境變數時,就會看到此問題:

USER=$(az vm show --resource-group QueryDemo --name TestVM --query "osProfile.adminUsername")
echo $USER
"azureuser"

使用 tsv 格式化,如下列查詢所示,以防止以類型資訊括住傳回值:

USER=$(az vm show --resource-group QueryDemo --name TestVM --query "osProfile.adminUsername" --output tsv)
echo $USER
azureuser

數據表輸出格式

格式 table 會將輸出列印為 ASCII 資料表,讓您輕鬆閱讀和掃描。 並非所有欄位都包含在數據表中,因此此格式最適合用來做為人類可搜尋的數據概觀。 數據表中未包含的欄位仍可篩選成查詢的一部分。

注意

某些索引鍵會篩選掉,而不會列印在數據表檢視中。 這些索引鍵為 idtypeetag。 若要查看這些值,您可以在多重選取哈希中變更索引鍵名稱。

az vm show --resource-group QueryDemo --name TestVM --query "{objectID:id}" --output table

我們可以使用先前的查詢來示範這個概念。 原始查詢會傳回 JSON 物件,其中包含資源群組中每個 VM 的名稱、OS 和系統管理員名稱:

az vm list --resource-group QueryDemo --query "[].{Name:name, OS:storageProfile.osDisk.osType, admin:osProfile.adminUsername}"
[
  {
    "Name": "Test-2",
    "OS": "Linux",
    "admin": "sttramer"
  },
  {
    "Name": "TestVM",
    "OS": "Linux",
    "admin": "azureuser"
  },
  {
    "Name": "WinTest",
    "OS": "Windows",
    "admin": "winadmin"
  }
]

結合 --output table 輸出格式時,數據行名稱會與多重選取哈希的值相符 displayKey ,讓您更輕鬆地略過資訊:

az vm list --resource-group QueryDemo --query "[].{Name:name, OS:storageProfile.osDisk.osType, Admin:osProfile.adminUsername}" --output table
Name     OS       Admin
-------  -------  ---------
Test-2   Linux    sttramer
TestVM   Linux    azureuser
WinTest  Windows  winadmin

下一步

若要深入瞭解 JMESPath 查詢,請參閱 JMESPath 教學課程

若要深入瞭解本文所述的其他 Azure CLI 概念,請參閱: