我正在尝试从 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 group list | select -p name
然后我得到大约 2 个充满空行的屏幕,没有显示任何内容。那么问题来了,上面的命令有什么问题?我应该如何修复它?
我尝试了以下实验来深入研究返回的对象的确切类型,并得到一些我不明白的结果。我希望这对拥有更多 Azure 和 Powershell 经验的人有意义。
假设您有一个 azure 帐户,以下是很容易重现问题的步骤。
pwsh
az login
az group list -o table
观察列表返回并正确格式化。
az group list | select -p name
观察几个充满空行的屏幕。没有文字。
情节变厚
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 在这里很粗糙。因此,为了仔细检查,我通过执行... (az group list)[0..10]
来查询该数组的前 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 的知识,以及生活可以很美好!爱你们,
艾伦
最佳答案
让我们解决这个问题。当我们指定 -o table
例如:
az group list -o table
我们告诉 Azure PowerShell CLI 获取您获得的 JSON 内容,并将其格式化为一个漂亮的表格。通常,我们不想使用 RAW JSON,也不想使用格式化表。在 PowerShell 中使用字符串数组也不是一件好事。在 PowerShell 中,我们希望使用“漂亮”的简单对象。那么,让我们看看其他获取信息的方法。让我们以你的例子为例,简单地将它保存到一个我们可以查看的变量中:
$GroupList = az group list
然后,如果我们看一下类型:
PS C:\> $GroupList.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
事实上,我们有一个对象数组。他们一定是我们的一群人……对吗?……不。这不是你想的那样。如果我们查看数组的大小并返回数组的前几个元素,我们将看到发生了什么:
PS C:\> $GroupList.Count
125
PS C:\Temp> $GroupList[0..2]
[
{
"id": "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/somegroup",
嗯,这不是我们想要的。该数组太大了......查看内容表明我们实际拥有的是JSON 文本 的每一行的数组。这意味着运行:
az group list | select -p name
或者:
$GroupList | select -p name
就是说,遍历数组,只输出“Name”属性。由于文本字符串中不存在“Name”属性,因此它只是输出一个空行。由于有几百行文本,我们得到了几百行空白。
那么为什么 PowerShell 接受输入并将其分解为由新行分隔的字符串数组?这不是很难用吗?这不是处理 JSON 格式文本的“好”方法吗?为什么我们不得到一根巨大的弦呢?这不是更容易处理和解析吗?这种奇怪的原因之一是什么?
使用 PowerShell,支持管道的需求插入了我们如何输出对象的决策:
"The primary purpose ... is to provide a way to ensure that the result of a pipeline execution is always an indexable collection." Quote
这就是为什么我们要输出一组对象(参见:@mklement0 answer here for more in depth discussion)来支持管道操作。如果我们看看文本文件是如何被读取和写入的,我们可以准确地强调为什么我们最终会出现这种特定的咳嗽 程序员咳嗽方便咳嗽......我的意思是奇怪。
为了进行设置,我们可以将输出直接通过管道传输到文本文件:
az group list | Out-File -FilePath List.json
哇,等一下,为什么这行得通? (在这种情况下,我想说 PowerShell 执行 魔术! ),我们不必纠结于遍历数组,附加以换行符结尾的字符串以获得一个以 EOF 结尾的巨大连续文本块,和我们想要的文本文件完全匹配?
真正发生的事情背后的简化原因?好吧,出于程序员的方便,
Out-File
获取字符串数组,遍历它,并为每个字符串执行一个简单的 File.WriteLine()
(对于 3 行 for 循环来说还不错!)。因此,我们毫不费力地生成了一个带有换行符的漂亮的 JSON 格式的文本文件。回读:PS C:\> $ListFromFile = Get-Content .\List.json
PS C:\> $ListFromFile.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
PS C:\> $ListFromFile.Count
125
是否相反。它获取文件,执行
File.ReadLine()
,将字符串附加到数组中,然后返回它。这就是为什么我们最终得到一个包含字符串的对象数组。现在,我们 真的 想要什么?我们从一开始就知道,我们不想使用一个巨大的字符串,我们 特别是 不想使用对象数组中的字符串,我们想要使用的是一个很好的原生
PSCustomObject
我们可以访问。这就是 PowerShell 最适合使用的东西,也是我们最适合使用的东西。所以,我们只需要转换我们的(大引号)“文本输入”,我们知道它被格式化为 JSON,并将其转换为一个对象:$List = $GroupList | ConvertFrom-Json
并查看计数和属性:
PS C:\> $List.Count
10
PS C:\> $List.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
PS C:\> $List[0].GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object
我们看到计数现在与我们拥有的组数相匹配,并且类型不再是字符串数组,而是实际的对象。所以... 现在 ,我们可以开始排序和选择:
PS C:\> $List | select -Property Name
Name
----
group0
group1
group2
group3
group4
group5
group6
group7
group8
group9
我们得到了我们真正想要的输出。
关于azure - 如何从 Azure 命令 "results"的 'az group list in powershell' 数组中只选择一个属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58738011/