如何使用 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 中运行查询,因为这些 shell 需要更少的转义字符。 若要确保查询示例语法正确,请选择所使用的 shell 的选项卡。

字典和列出 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"
]

这些值按查询中给出的顺序在结果数组中列出。 由于结果是数组,因此没有与结果关联的键。 若要获取字典而不是数组,请参阅下一部分。

重命名查询中的属性

若要在查询多个值时获取字典而不是数组,请使用 { }多选哈希) 运算符。 多选哈希的格式为 {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 的表达式将包含在输出中。

第一个查询演示如何列出与你的账户相连并且其isDefault属性为 true 的所有 Azure 订阅的名称。 第二个和第三个查询显示了列出其 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 规范

在最后一节中,您展平数组以获取资源组中所有虚拟机的完整清单。 使用筛选器时,此输出只能限制为 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)此概念来演示此概念,该概念检查字符串是否包含子字符串。 此命令查找使用 SSD 存储的所有 VM 的 OS 磁盘:

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 资源 ID 或资源名称)中检索值,并将值存储在本地环境变量中。 默认情况下,结果以 JSON 格式返回,在处理用字符括起来 " 的 JSON 字符串时,这可能是个问题。 如果命令输出直接分配给环境变量, shell 可能无法解释 引号。 以下示例中显示了向环境变量分配查询结果的问题:

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 概念,请参阅: