【问题标题】:Export data in the order it was added - PowerShell Export-Csv按添加顺序导出数据 - PowerShell Export-Csv
【发布时间】:2018-06-30 06:27:24
【问题描述】:

我有这个代码

function get-data()
{
   $rec=[PSCustomObject]@()
   $DLGP = "" | Select "Name","Grade","Score"

   foreach($record in $data) 
   {
       $DLGP.Name=$record.name
       $DLGP.Grade=$record.grade
       $DLGP.Score=$record.score
       $rec += $DLGP
   }
   return $rec
}

$mydata=get-data
$mydata | Export-Csv -Path $outputPath -NoTypeInformation

问题是,数据没有按照我添加到$rec的顺序导出

如何按添加顺序导出?

【问题讨论】:

  • 默认情况下,[PSCustomObject] 是无序的。由于 Powerschell 版本 4 或 5 我猜有订购的自定义对象。只需在[PSCutomObject] 前面添加[ordered] .... 就像这样:[ordered][PSCostomObject]
  • @Olaf:[pscustomobject] 实例始终按定义顺序枚举其属性。它是 hashtables,其条目以无保证的顺序枚举; PSv3 引入了[ordered] @{ ... } 以允许定义有序哈希表文字,其条目也按定义顺序枚举,并且还允许将哈希表文字转换为[pscustomobject],在这种情况下[ordered]隐含 - 在PSv2 中 - 这样演员阵容根本不起作用(没有操作)。但是,OP 的问题与会员订购无关 - 请参阅我的回答。 [ordered] 仅在 @{ ... } 之前有效。

标签: powershell pscustomobject


【解决方案1】:

甚至不用你的函数,一个简单的

$mydata = $data | select Name,Grade,Score

会产生预期的结果。

您的功能在 IMO 过于复杂:

$Data = @"
Name,Grade,Score,Dummy
Anthoni,A,10,v
Brandon,B,20,x
Christian,C,30,y
David,D,40,z
"@ | ConvertFrom-Csv

function get-data() {
   ForEach($record in $data) {
       [PSCustomObject]@{
           Name =$record.name
           Grade=$record.grade
           Score=$record.score
       }
   }
}

$mydata=get-data
$mydata # | Export-Csv -Path $outputPath -NoTypeInformation

在这里返回几乎相同的顺序:

Name      Grade Score
----      ----- -----
Anthoni   A     10
Brandon   B     20
Christian C     30
David     D     40

【讨论】:

    【解决方案2】:

    LotPings' helpful answer 提供有效的解决方案。

    至于你尝试了什么

    通过仅构造一个单个 [pscustomobject] 实例在循环之外

    $DLGP = "" | Select "Name","Grade","Score"
    

    然后在每次循环迭代中只更新一个实例的属性:

    $DLGP.Name=$record.name
    # ....
    

    有效地将相同的 [pscustomobject] 实例多次添加到结果数组中,而不是在每次迭代中创建一个不同的对象。

    由于重复更新同一个对象,该对象最终具有输入集合中 last 对象的属性,$data

    顺便说一句:

    [PSCustomObject] @() 实际上与@() 相同:[PSCustomObject]忽略,你会得到一个[object[]] 数组。

    要将数组键入为包含 [PSCustomObject] 实例的数组,您必须使用 array 类型的强制转换:[PSCustomObject[]] @()

    但是,鉴于 any 类型的实例可以转换为 [PSCustomObject] - 这实际上与 [psobject] 相同 - 这没有提供类型安全性和性能优势。

    此外,由于您的 $rec 变量不受类型限制(它被定义为 $rec = [<type>] ... 而不是 [<type>] $rec = ...)并且您使用 += 来“添加到”数组(这总是需要在幕后创建新实例),$rec 将在第一次 += 操作后恢复为 [object[]] 数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-07
      • 2023-03-20
      • 2016-04-30
      • 2019-11-25
      相关资源
      最近更新 更多