你当前正在访问 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 name
VMName
,引用规则将在 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 运算符来完成。
此运算符采用谓词作为其内容。 谓词是指其求值结果可能为 true
或 false
的任何语句(包括布尔属性)。 所含谓词的求值结果为 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
输出运行查询,然后进行格式设置。
本部分将介绍 tsv
和 table
格式设置以及每个格式的一些用例。 有关输出格式的详细信息,请参阅 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 表的形式列显输出,因此可以轻松阅读和扫描输出。 并非所有字段都会包含在表中,因此,最好将此格式用来对数据进行可供人工搜索的概览。 未包含在表中的字段仍可作为查询的一部分进行筛选。
备注
某些键已筛选掉,未在表视图中输出。 这些键为 id
、type
和 etag
。 若要查看这些值,可以在多选哈希中更改键名。
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 概念,请参阅: