PowerShell,从变量中提取多个数组以生成单个变量
Posted
技术标签:
【中文标题】PowerShell,从变量中提取多个数组以生成单个变量【英文标题】:PowerShell, Pulling out multiple arrays from an variable to make a single variable 【发布时间】:2022-01-09 09:25:22 【问题描述】:我有一个变量$metrics
,由于缺乏确定性,我将其称为数组数组?我可能错了,但这是我能想到的最好的。
这是变量。
PS C:\Windows\system32> $metrics
Id : cpuUtil01
Label : CPUUtilization
Messages :
StatusCode : Complete
Timestamps : 11/27/2021 7:00:00 PM, 11/27/2021 7:05:00 PM, 11/27/2021 7:10:00 PM, 11/27/2021 7:15:00 PM...
Values : 51.22, 31.3833333333333, 31.4116666666667, 31.5283333333333...
我想将$metrics.timestamps
和$metrics.values
提取出来,以便将它们导出到CSV 文件中,这样我就可以使用Excel 的折线图。我不知道如何将它们两个提取到一个变量中。
我可以一次做一个,如下所示,但是我如何加入他们以便我有一个可以使用的 CSV。
$o = ""
$out = @()
foreach ($GetMetric in $Metrics.timestamps)
$o = New-Object -TypeName PSCustomObject -Property ([ordered]@
TimeStampUTC = $GetMetric;
)
$out += $o
$out
TimeStampUTC
------------
11/27/2021 7:00:00 PM
11/27/2021 7:05:00 PM
11/27/2021 7:10:00 PM
11/27/2021 7:15:00 PM
11/27/2021 7:20:00 PM
11/27/2021 7:25:00 PM
11/27/2021 7:30:00 PM
11/27/2021 7:35:00 PM
11/27/2021 7:40:00 PM
11/27/2021 7:45:00 PM
$o = ""
$out = @()
foreach ($GetMetric in $Metrics.values)
$o = New-Object -TypeName PSCustomObject -Property ([ordered]@
Values = $GetMetric;
)
$out += $o
$out
Values
------
51.22
31.3833333333333
31.4116666666667
31.5283333333333
31.4166666666667
31.425
31.4916666666667
31.4166666666667
31.325
31.5916666666667
我想要的是一个具有两个值的变量,如下所示,因此我可以将其输出到 csv 文件。
PS C:\Windows\system32> $output
TimeStampUTC Values
------------ ------
11/27/2021 7:00:00 PM 51.22
11/27/2021 7:05:00 PM 31.3833333333333
11/27/2021 7:10:00 PM 31.4116666666667
11/27/2021 7:15:00 PM 31.5283333333333
11/27/2021 7:20:00 PM 31.4166666666667
11/27/2021 7:25:00 PM 31.425
11/27/2021 7:30:00 PM 31.4916666666667
11/27/2021 7:35:00 PM 31.4166666666667
11/27/2021 7:40:00 PM 31.325
11/27/2021 7:45:00 PM 31.5916666666667
你会怎么做?
非常感谢任何帮助。
-橄榄球
这是我对 .GetType() 和 Get-Member 的输出
PS C:\Windows\system32> $metrics.GeTtype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True List`1 System.Object
PS C:\Windows\system32> $metrics.Values.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
PS C:\Windows\system32> $metrics | Get-Member
TypeName: Amazon.CloudWatch.Model.MetricDataResult
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Id Property string Id get;set;
Label Property string Label get;set;
Messages Property System.Collections.Generic.List[Amazon.CloudWatch.Model.MessageData] Messages get;set;
StatusCode Property Amazon.CloudWatch.StatusCode StatusCode get;set;
Timestamps Property System.Collections.Generic.List[datetime] Timestamps get;set;
Values Property System.Collections.Generic.List[double] Values get;set;
【问题讨论】:
【参考方案1】:您尝试执行的操作通常称为“合并数组” 或“连接数组”。有很多方法可以解决这个问题,例如,使用 for
循环。
回答您的第一个问题,$metrics
是一个object
,并且作为任何对象,它可以具有属性和方法。在这种情况下,您的 object
有 3 个属性,它们是 arrays
。为了对将来如何处理此问题提供一些看法,了解.GetType()
方法和Get-Member
的关键。
这是使用[PSCustomObject]
重新创建的对象:
$metrics = [pscustomobject]@
Id = 'cpuUtil01'
Label = 'CPUUtilization'
Messages = @()
StatusCode = 'Complete'
Timestamps = '11/27/2021 7:00:00 PM','11/27/2021 7:05:00 PM','11/27/2021 7:10:00 PM'
Values = '51.22','31.3833333333333','31.4116666666667','31.5283333333333'
现在我们可以付诸实践了:
PS /> $metrics.GeTtype()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False PSCustomObject System.Object
PS /> $metrics.Values.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
PS /> $metrics | Get-Member
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Id NoteProperty string Id=cpuUtil01
Label NoteProperty string Label=CPUUtilization
Messages NoteProperty Object[] Messages=System.Object[]
StatusCode NoteProperty string StatusCode=Complete
Timestamps NoteProperty Object[] Timestamps=System.Object[]
Values NoteProperty Object[] Values=System.Object[]
现在回答主要问题,如何合并两个数组?:
首先我们需要知道两者是否具有相同的length
,否则我们会丢失信息:
$maxCount = [math]::Max($metrics.TimeStamps.Count, $metrics.Values.Count)
然后使用 for
循环遍历每个数组的每个元素,从它们的值中创建一个新对象:
$result = for($i = 0; $i -lt $maxCount; $i++)
[pscustomobject]@
TimeStamps = $metrics.TimeStamps[$i]
Values = $metrics.Values[$i]
PS /> $result
TimeStamps Values
---------- ------
11/27/2021 7:00:00 PM 51.22
11/27/2021 7:05:00 PM 31.3833333333333
11/27/2021 7:10:00 PM 31.4116666666667
11/27/2021 7:15:00 PM 31.5283333333333
【讨论】:
这就像一个魅力,感谢您提供有关我正在使用的内容的信息。我每天都在努力学习新东西!这是我的输出 @Rugbyball 很乐意为您提供帮助,也很高兴您能学到新东西 :) 我编辑了问题以包括我的 .GetType() 和 Get-Member。我和你的唯一区别在于$metrics.GeTtype()
我的是True
for IsSerial
而你的是False
不确定这是否会改变任何东西。刚好注意到它。
另外,不是什么大不了的,马上拿起它。但是对于任何其他后续。我注意到一行中有一个错字。 $maxCount = [math]::Max($matrics.TimeStamps.Count, $metrics.Values.Count)
应该是 $maxCount = [math]::Max($metrics.TimeStamps.Count, $metrics.Values.Count)
同样,没什么大不了的,只是指出可能使用它的其他人。再次感谢Santiago Squarzon
@Rugbyball 很好,感谢您指出这一点。我会编辑我的答案。 IsSerial
来自Type.IsSerializable Property
以上是关于PowerShell,从变量中提取多个数组以生成单个变量的主要内容,如果未能解决你的问题,请参考以下文章