你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

如何使用 JMESPath 查询来查询 Azure CLI 命令输出

Azure CLI 使用 --query 参数针对命令的结果执行 JMESPath 查询。 JMESPath 是用于 JSON 的查询语言,提供在 CLI 输出中选择和修改数据的功能。

Azure CLI 中的所有命令都支持 --query 参数。 本文介绍如何使用 JMESPath 的功能并提供查询示例。 了解可用于在“概念”选项卡下进行查询的 JMESPath 概念。请参阅“示例”选项卡下的 JMESPath 查询示例。

Azure CLI 使用查询来选择和修改 Azure CLI 命令的输出。 将在客户端的 Azure CLI 命令返回的 JSON 对象上执行查询,然后再执行任何显示格式设置。

查询中需要的转义字符因环境而异。 建议在 Azure CloudShell 或 cmd 中运行查询,因为这些 shell 需要的转义字符较少。 若要确保查询示例语法正确,请为你要使用的 shell 选择相应的选项卡。

字典和列表 CLI 结果

CLI 命令结果首先被视为 JSON 进行查询,即使输出格式不是 JSON 也是如此。 CLI 结果为 JSON 数组或字典。 数组是可以进行索引的对象的序列,字典是通过密钥进行访问的无序对象。

下面是数组的一个示例:

[ 
  1,
  2,
  3
]

下面是字典的一个示例:

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

可以返回多个对象的命令会返回一个数组,而始终只返回单个对象的命令则返回字典。

获取字典中的属性

处理字典结果时,可以只使用密钥来访问顶级属性。 . (子表达式) 字符用于访问嵌套字典的属性。 在介绍查询之前,让我们先看看 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 也支持逻辑 AND (&&)、OR (||) 和 NOT (!)。 表达式可以在括号中进行分组,因此可以形成更复杂的谓词表达式。 有关谓词和逻辑运算的完整详细信息,请参阅 JMESPath specification(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 列表,以显示磁盘大小大于或等于 50GB 的 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 存储作为其 OS 磁盘的所有 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 specification - Built-in Functions(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 specification - Built-in Functions(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 概念,请参阅: