【问题标题】:Transpose to object but without values, yet转置到对象但没有值,但
【发布时间】:2021-06-20 14:11:18
【问题描述】:

我正在从 ESXi 主机导入 esxtop 数据。导入给了我两组数据。第一个是我将从中获取数据的所有字段的列表。第二个是这些字段中的数据。

字段列表是这样的:

|SchedGroup|GroupID|GroupName|IsValid|IsVM|VMName|TimerPeriod|CPUAllocMin|CPUAllocMax|

我将其转换为名为 $Headercols 的 Selected.System.String:

header                
------                
SchedGroup            
GroupID               
GroupName             
IsValid               
IsVM                  
VMName                
TimerPeriod           
CPUAllocMin           
CPUAllocMax

但我实际上需要它在列中,而不是在行中。因为稍后我想添加包含数据的“记录”/“行”。我尝试使用 add-member 转换为列,但这需要一个名称和一个值,但我还不知道该值。

这里的示例只有几行,但会增长到 33 行,所以我宁愿将它们填充在一个循环中,而不是专门针对每一行。

稍后我会收到这样的数据:

|SchedGroup|13567824|vm.4430541|1|1|BJLDC002|10416|0|-1|
|SchedGroup|12883482|vm.4316334|1|1|VCDJAGTEST|15260|0|-1|
|SchedGroup|13558449|vm.4429332|1|1|BJLADF02|1000|0|-1|

(示例有 3 行,每行一个虚拟机,但它可以是更多行与虚拟机。) 我知道如何将行拆分为单独的值,但就像标题一样,我不知道如何扩展对象。

我在谷歌上搜索的所有示例都立即添加名称和值,我似乎无法理解我应该如何使用它。

【问题讨论】:

  • 这是因为大多数格式化和导出 cmdlet 不希望您“创建列” - 您只需创建对象,Format-TableExport-Csv 等 cmdlet 将推断 对象属性中的逻辑列名。您正在尝试解决一个不存在的问题
  • 好的,我解决这个问题的方式是错误的吗?我怎样才能得到一个看起来像这样的对象:SchedGroup,GroupID,GroupName,IsValid,IsVM,VMName,TimerPeriod SchedGroup,13567824,vm.4430541,1,1,BJLDC002,10416 SchedGroup,12883482,vm.4316334,1 ,1,VCDJAGTEST,15260 SchedGroup,13558449,vm.4429332,1,1,BJLADF02,1000
  • 这只是一个 csv 表格格式。只需使用正则表达式将 | 替换为 ','。

标签: arrays powershell object


【解决方案1】:

但我实际上需要它在列中,而不是在行中。

您已经超前了 - “列”和“行”与我们可能如何格式化(或显示)数据有关 - 但现在我们需要以某种方式导入和解析数据。

我建议修剪前导和尾随 |,此时我们可以将数据集视为 CSV(使用 | 而不是 , 作为分隔符 - PSV?):

# Read header list and split into individual strings
$headerString = Get-Content .\path\to\headers.txt |Select -First 1
$headers = $headerString.Split('|', [StringSplitOptions]::RemoveEmptyEntries)

# Read data set, remove the leading and trailing pipes
$dataSetRaw = (Get-Content .\path\to\data.txt) -replace '^\||\|$'

# Convert to structured objects
$data = $dataSetRaw |ConvertFrom-Csv -Delimiter '|' -Header $headers

ConvertFrom-Csv 将为每条记录创建一个对象,此时您会发现大多数格式化 cmdlet 完全符合您的预期:

PS ~> $data |Format-Table

SchedGroup GroupID  GroupName  IsValid IsVM VMName     TimerPeriod CPUAllocMin CPUAllocMax
---------- -------  ---------  ------- ---- ------     ----------- ----------- -----------
SchedGroup 13567824 vm.4430541 1       1    BJLDC002   10416       0           -1
SchedGroup 12883482 vm.4316334 1       1    VCDJAGTEST 15260       0           -1
SchedGroup 13558449 vm.4429332 1       1    BJLADF02   1000        0           -1

【讨论】:

  • 谢谢,成功了。在使用您的解决方案时,我首先没有让它工作,因为我忽略了“[StringSplitOptions]::RemoveEmptyEntries”部分。我确信我可以忽略它,因为所有数据总是在没有空格的情况下接收。但结果是 convertfrom-csv 然后在 $headers 上失败了。添加“[StringSplitOptions]::RemoveEmptyEntries”后,立即生效。
【解决方案2】:

继续我的评论...

'|SchedGroup|GroupID|GroupName|IsValid|IsVM|VMName|TimerPeriod|CPUAllocMin|CPUAllocMax|' -replace '\|', ','  -replace '^,|,\s*$'
# Results
<#
SchedGroup,GroupID,GroupName,IsValid,IsVM,VMName,TimerPeriod,CPUAllocMin,CPUAllocMax
#>

然而,你说你的数据是以这种方式来的......

SchedGroup,13567824,vm.4430541,1,1,BJLDC002,10416 
SchedGroup,12883482,vm.4316334,1,1,VCDJAGTEST,15260 
SchedGroup,13558449,vm.4429332,1,1,BJLADF02,1000

...然后只需导入它并分配标题。

$Headers = @('|SchedGroup|GroupID|GroupName|IsValid|IsVM|VMName|TimerPeriod|CPUAllocMin|CPUAllocMax|' -replace '\|', ','  -replace '^,|,\s*$')
Import-Csv -Path 'SomeFilePath' -Header $Headers

【讨论】:

  • 不错。这个问题有点不清楚,但我的印象是这些值的格式相同,即。 |A|B|C|
  • @Mathias R. Jessen... Roger 说,当您将他的记录数据复制到记事本时,它不是行,而是一行。然而,我也认为,这是一个发布错误。无论哪种方式,你和我提供的应该足以让 OP 到达他们需要的地方。
  • 我的数据不是来自 CSV,而是来自这个: $esxtopCounters = $serviceView.ExecuteSimpleCommand("CounterInfo") 但你指出我的方式是正确的。连同@MathiasR.Jessen 的回复,我能够解决它。
  • 很高兴知道我们为您提供了所需的灯泡时刻。在外面小心/保持安全。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-07
  • 2017-03-26
  • 2019-12-01
相关资源
最近更新 更多