PowerShell, извлекающий несколько массивов из переменной для создания одной переменной

#arrays #powershell #variables #hashtable

#массивы #powershell #переменные #хеш-таблица

Вопрос:

У меня есть переменная $metrics , и из-за отсутствия уверенности я называю это массивом массивов? Возможно, я ошибаюсь, но это лучшее, что я могу придумать.

Вот переменная.

 PS C:Windowssystem32> $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:Windowssystem32> $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
 

Как бы вы это сделали?

Любая помощь приветствуется.

-Rugbyball

<отредактировано — дополнительные примечания>

Вот мой вывод для .GetType() и Get-Member

 PS C:Windowssystem32> $metrics.GeTtype()

IsPublic IsSerial Name                                     BaseType                                                                                                          
-------- -------- ----                                     --------                                                                                                          
True     True     List`1                                   System.Object                                                                                                     



PS C:Windowssystem32> $metrics.Values.GetType()

IsPublic IsSerial Name                                     BaseType                                                                                                          
-------- -------- ----                                     --------                                                                                                          
True     True     Object[]                                 System.Array                                                                                                      



PS C:Windowssystem32> $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 это an 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
 

Комментарии:

1. Это сработало как шарм, и спасибо за информацию о том, с чем я работал. Я стремлюсь каждый день узнавать что-то новое! Вот мой вывод для

2. @Rugbyball рад помочь и рад, что вы смогли узнать что-то новое 🙂

3. Я отредактировал вопрос, чтобы включить мой . GetType() и Get-Member . Единственное отличие моего от вашего было в $metrics.GeTtype() моем True IsSerial , когда вы False не были уверены, что это что-то меняет или нет. Просто случайно заметил это.

4. Кроме того, ничего особенного, сразу же понял это. Но для любого другого последующего. я заметил опечатку в одной строке. $maxCount = [math]::Max($matrics.TimeStamps.Count, $metrics.Values.Count) Должно быть $maxCount = [math]::Max($metrics.TimeStamps.Count, $metrics.Values.Count) , опять же, ничего особенного, просто указывая на других, которые могут это использовать. Еще раз спасибо Santiago Squarzon

5. @Rugbyball Хороший улов, спасибо, что указали на это. Я отредактирую свой ответ. IsSerial происходит из Type.IsSerializable Property