我正在尝试从az group listpowershell 中的 Azure 命令返回的“结果”(对象?)数组中仅选择一个属性?
我知道这听起来微不足道,但这就是奇怪的地方,我希望有一个简单的解释。
如果我运行 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
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试Name通过执行仅选择属性
az 组列表 | 选择 -p 名称
然后我得到大约 2 个充满空行的屏幕,没有显示任何内容。那么问题来了,上面的命令有什么问题?我应该如何修复它?
我尝试了以下实验来深入研究返回的对象的确切类型,并得到一些我不明白的结果。我希望这对拥有更多 Azure 和 Powershell 经验的人有意义。
假设您有一个 azure 帐户,以下是很容易重现问题的步骤。
pwshaz loginaz 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
}
]
Run Code Online (Sandbox Code Playgroud)
然而,(az group list).getType()返回
[
... 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
}
]
Run Code Online (Sandbox Code Playgroud)
最后,希望拼图的最后两块
PS src> (az group list).getType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
Run Code Online (Sandbox Code Playgroud)
所以来自的返回类型az group list似乎是一个array of objects或者可能是一个数组object[],我的powershell在这里很粗糙。因此,为了仔细检查,我通过执行...查询该数组的前 10 个元素(az group list)[0..10],结果奇怪地返回10 strings!. 好吧,我知道它应该是 10 个字符串,只是因为它是一台计算机,如果它是这样,那么它就是它真正的样子。我只是不明白为什么。
PS src> (az group list)[0].getType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
Run Code Online (Sandbox Code Playgroud)
所以所有这些,长话短说,我想知道,你如何从 azure 查询的结果中只选择一个属性?就我而言,我只想显示我所有资源组的名称。
这az group list | select -p name应该可行,但不可行,我想知道如何正确执行,并在此过程中找出它不起作用的原因,我们都可以在此过程中了解有关 Azure 和 Powershell 的知识,以及生活可以很棒!
爱你们所有人,艾伦
4c7*_*b41 16
哇,这么多文字,就像这样简单的事情:
az group list --query '[].name' -o tsv
Run Code Online (Sandbox Code Playgroud)
在查询中,我们使用[],因为命令的输出list是一个数组。接下来,我们选择所需的单列name。如果我们想选择多于一列,我们会使用[name, BaseType]. Azure CLI 中的所有“list”命令都会返回一个数组,但如果使用返回单个结果的任何其他 CLI 命令,我们只需使用--query 'name'.
默认情况下,Azure CLI 命令的输出为 json。我们使用--output或-o来更改格式,我们选择它是tsv因为它提供了最干净的输出。
让我们解决这个问题。当我们指定-o table例如:
az group list -o table
Run Code Online (Sandbox Code Playgroud)
我们告诉 Azure PowerShell CLI 获取您获得的 JSON 内容,并将其格式化为一个漂亮的表格。通常,我们不想使用 RAW JSON,也不想使用格式化表。在 PowerShell 中使用字符串数组也不是一件好事。在 PowerShell 中,我们希望使用“漂亮”的简单对象。那么,让我们看看其他获取信息的方法。让我们以你的例子为例,简单地将它保存到一个我们可以查看的变量中:
$GroupList = az group list
Run Code Online (Sandbox Code Playgroud)
然后,如果我们看一下类型:
PS C:\> $GroupList.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
Run Code Online (Sandbox Code Playgroud)
事实上,我们有一个对象数组。他们一定是我们的一群人……对吗?……不。这不是你想的那样。如果我们查看数组的大小并返回数组的前几个元素,我们将看到发生了什么:
PS C:\> $GroupList.Count
125
PS C:\Temp> $GroupList[0..2]
[
{
"id": "/subscriptions/12345678-1234-1234-1234-123456789012/resourceGroups/somegroup",
Run Code Online (Sandbox Code Playgroud)
嗯,这不是我们想要的。数组太大了......查看内容表明我们实际拥有的是 JSON text的每一行的数组。这意味着运行:
az group list | select -p name
Run Code Online (Sandbox Code Playgroud)
或者:
$GroupList | select -p name
Run Code Online (Sandbox Code Playgroud)
就是说,遍历数组,只输出“Name”属性。由于文本字符串中不存在“Name”属性,因此它只是输出一个空行。由于有几百行文本,我们得到了几百行空白。
那么为什么 PowerShell 接受输入并将其分解为由新行分隔的字符串数组?这不是很难用吗?这不是处理 JSON 格式文本的“好”方法吗?为什么我们不得到一根巨大的弦呢?这不是更容易处理和解析吗?这种奇怪的原因之一是什么?
使用 PowerShell,支持管道的需求推动了我们如何输出对象的决策:
“主要目的......是提供一种方法来确保管道执行的结果始终是一个可索引的集合。” 引用
这就是为什么我们会输出一组对象(请参阅:@mklement0 此处的答案以获得更深入的讨论)以支持管道操作。如果我们看看文本文件是如何被读取和写入的,我们可以准确地强调为什么我们最终会出现这种特定的咳嗽程序员咳嗽方便咳嗽......我的意思是奇怪。
为了进行设置,我们可以将输出直接通过管道传输到文本文件:
az group list | Out-File -FilePath List.json
Run Code Online (Sandbox Code Playgroud)
哇,等一下,为什么这行得通?(在这种情况下,我想说 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
Run Code Online (Sandbox Code Playgroud)
是否相反。它获取文件,执行 a File.ReadLine(),将字符串附加到数组中,然后返回它。这就是为什么我们最终得到一个包含字符串的对象数组。
现在,我们真正想要的是什么?好吧,我们从一开始就知道,我们不想使用一个巨大的字符串,我们尤其不想使用对象数组中的字符串,我们想要使用的是一个PSCustomObject我们可以访问的不错的原生字符串。这就是 PowerShell 最适合使用的东西,也是我们最适合使用的东西。所以,我们只需要转换我们的(大引号)“文本输入”,我们知道它被格式化为 JSON,并将其转换为一个对象:
$List = $GroupList | ConvertFrom-Json
Run Code Online (Sandbox Code Playgroud)
并查看计数和属性:
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
Run Code Online (Sandbox Code Playgroud)
我们看到计数现在与我们拥有的组数相匹配,并且类型不再是字符串数组,而是实际的对象。所以......现在,我们可以开始排序和选择:
PS C:\> $List | select -Property Name
Name
----
group0
group1
group2
group3
group4
group5
group6
group7
group8
group9
Run Code Online (Sandbox Code Playgroud)
我们得到了我们真正想要的输出。
| 归档时间: |
|
| 查看次数: |
1796 次 |
| 最近记录: |