我正试图从一个“结果”(对象?),这些命令来自powershell中的Azure命令az group list
?
我知道这听起来很琐碎,但这里是它变得奇怪的地方,我希望有一个简单的解释。
如果我运行Azure命令az group list -o table
(在我使用az login
成功登录之后),我会得到以下典型响应
PS src> az group list -o table
Name Location Status
---------------- ---------- ---------
group0 westeurope Succeeded
group1 westeurope Succeeded
group2 uksouth Succeeded
group3 westeurope Succeeded
group4 westeurope Succeeded
group5 westeurope Succeeded
group6 westeurope Succeeded
group7 uksouth Succeeded
group8 westeurope Succeeded
group9 westeurope Succeeded
字符串
但是,如果我尝试通过执行以下操作仅选择Name
属性
az组表|select -p名称
然后我得到大约2个屏幕充满了空行,没有显示任何内容。所以问题是,上面的命令有什么问题?我该怎么解决呢?
我尝试了下面的实验来深入了解返回对象的确切类型,并得到了一些我不理解的结果。我希望这对有更多Azure和PowerShell经验的人来说是有意义的。
假设您有一个azure帐户,下面是非常容易重现问题的步骤。
1.启动powershell,例如在mac终端上,键入pwsh
1.登录Azure az login
1.型号az group list -o table
观察列表返回并且格式正确。
1.型号az group list | select -p name
观察几个满是空白行的屏幕。没有短信。
1.抓着你的头,想知道刚刚发生了什么事?(咧嘴笑)
情节越来越复杂
az group list
自己返回了几个屏幕,上面都是
[
... lots of these ...
{
"id": "/subscriptions/this-is-super-wierd-i-cant-select-name-prop/resourceGroups/spikes",
"location": "westeurope",
"managedBy": null,
"name": "spikes",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {},
"type": null
}
]
型
但是,(az group list).getType()
返回
PS src> (az group list).getType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
型
最后,希望最后两块拼图
PS src> (az group list)[0].getType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
型
所以从az group list
返回的类型看起来是一个array of objects
或者可能是一个object[]
的数组,我的powershell在这里很粗糙。为了仔细检查,我查询数组的前10个元素,方法是... (az group list)[0..10]
,返回奇怪的10 strings!
。好吧,我知道它应该是10个字符串,只是因为它是一台计算机,如果这就是它,那么,这就是它真正的样子。我只是不明白为什么。
[
{
"id": "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/somegroup",
"location": "westeurope",
"managedBy": null,
"name": "admin",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {},
"type": null
型
所以所有这些,长话短说,我想知道,你如何从Azure查询的结果中选择一个属性?在本例中,我只想显示所有资源组的名称。
这个az group list | select -p name
应该工作,但没有,我想知道如何正确地做,并在这个过程中找出为什么它不工作,我们都可以在这个过程中学习一些关于Azure和powershell的东西,生活可以很棒!
爱你们所有人艾伦
2条答案
按热度按时间ztmd8pv51#
让我们一起解决这个问题。当我们指定
-o table
时,例如:字符串
我们对Azure PowerShell CLI说,获取您获得的JSON内容,并将其格式化为一个漂亮的表。通常,我们不想使用RAW JSON,也不想使用格式化的表。在PowerShell中使用字符串数组也不是一件好事。在PowerShell中,我们希望使用“漂亮”的简单对象。那么,让我们看看其他获取信息的方法。让我们以您的示例为例,简单地将其保存到一个变量中,我们可以查看:
型
如果我们看类型:
型
事实上,我们有一个对象数组。它们 * 必须 * 是我们组的数组...对吧?不。不是你想的那样如果我们查看数组的大小并返回数组的前几个元素,我们将看到发生了什么:
型
这不是我们想要的数组太大了...查看内容可以发现,我们实际上拥有的是JSONtext每行的数组。这意味着运行:
型
或者:
型
循环遍历数组,只输出“Name”属性。由于“Name”属性不存在于文本字符串中,因此它只输出一个空行。由于有几百行文本,我们得到几百行空白。
那么,为什么PowerShell要接受输入并将其分解为一个由新行分隔的字符串数组呢?这不是有点难用吗这难道不是处理JSON格式文本的“好”方法吗?为什么我们不买一根大绳子呢?这不是更容易处理和解析吗?这奇怪的一个原因是什么?
在PowerShell中,支持管道的需求决定了我们如何输出对象:
“主要目的……是提供一种方法来确保管道执行的结果始终是可索引的集合。”
这就是为什么我们得到一个输出的对象数组(参见:@mklement0回答这里更深入的讨论),以支持管道操作。如果我们看看文本文件是如何被读取和写入的,我们就可以确切地强调为什么我们最终会得到这个特定的 * 咳嗽 * 程序员 * 咳嗽 * 方便 * 咳嗽 *...我是说奇怪。
要设置这些,我们可以将输出直接管道到文本文件:
型
等等,这怎么能成功?(在这种情况下,我喜欢说PowerShell确实有魔力!),难道我们不需要在数组中进行循环,追加以换行符结尾的字符串,以获得一个以EOF结尾的巨大的连续文本块,并且完全匹配我们想要的文本文件吗?
一个简单的原因背后到底发生了什么?好吧,为了方便程序员,
Out-File
接受字符串数组,遍历它,并对每个字符串执行一个简单的File.WriteLine()
(对于一个3行的for循环来说,这还不错!)。因此,我们只是生成了一个漂亮的JSON格式的文本文件,其中包含换行符,而无需费力。阅读回:型
反其道而行之它接受文件,执行
File.ReadLine()
,将字符串追加到数组中,然后返回数组。这就是为什么我们最终得到一个包含字符串的对象数组。我们到底想要什么?我们从一开始就知道,我们不想处理一个巨大的字符串,我们 * 特别是 * 不想处理对象数组中的字符串,我们想处理的是一个很好的原生
PSCustomObject
,我们可以访问。这就是PowerShell最好的工作,这就是我们最好的工作。因此,我们只需将我们的(大空引号)“文本输入”转换为JSON格式,并将其转换为对象:型
查看计数和属性:
型
我们看到计数现在与我们有多少组相匹配,类型不再是字符串数组,而是实际的对象。所以... * 现在 *,我们可以开始排序和选择:
型
我们得到了我们真正想要的输出。
ippsafx72#
哇,这么多的文字这么简单的东西:
字符串
在查询中,我们使用
[]
,因为list
命令的输出是一个数组。接下来,我们选择所需的单列name
。如果我们想要选择多个列,我们将使用[name, BaseType]
。Azure CLI中的所有“list”命令都返回一个数组,但如果使用任何其他返回单个结果的CLI命令,我们只需使用--query 'name'
。默认情况下,Azure CLI命令的输出是json。我们使用
--output
或-o
来更改格式,选择tsv
是因为它提供了最干净的输出。