【问题标题】:Is there a way to force powershell -Export-CSV cmdlet to maintain a specific column order?有没有办法强制 powershell -Export-CSV cmdlet 保持特定的列顺序?
【发布时间】:2013-10-01 14:20:31
【问题描述】:

我是 powershell 新手,所以脚本是来自站点的各种示例的科学怪人。

我的问题是如何确保我为 DataTable 创建的 csv 文件保持我指定的列顺序?

我的脚本这样做是为了填充 csv 标头和值,如下所示:

...snip...
$dataTable | ForEach-Object {
            $csv+=New-Object PSObject -Property @{
                program_code=$_.ProgramCode;
                first_name=$_.FirstName;
                last_name=$_.LastName;
                email=$_.email;
                phone=$_.phone;
                phone2=$_.otherphone;
                address=$_.addr1;
                address2=$_.addr2;
                city=$_.city;
                state=$_.state;
                postal_code=$_.Zip;
                country=$_.Country;
                grad_year=$_.HsGradDate;
                lead_date=$_.LeadDate;
                lead_source=$_.LeadSource;
                school_status=$_.SchoolStatus;
        }
        }
    $csv | Export-CSV C:\scripts\NewLeads$(Get-Date -Format yyyyMMdd).csv -notype -Append
...snip...

我希望文件必须按照我在脚本中指定的顺序排列,但是当我在记事本或 Excel 中打开它时,这些列会以看似随机的顺序出现。关键字似乎是因为他们可能有一些自己排序的方法。

【问题讨论】:

    标签: powershell csv


    【解决方案1】:

    在 PowerShell V3 中,而不是:

            $csv+=New-Object PSObject -Property @{
    

    我会使用:

            $csv+=[pscustomobject]@{
    

    当您将散列 literal 转换为 [ordered] 或 [pscustomobject] 时,PowerShell V3 解析器将保留键的顺序。这种方法的一个小好处 - 它也会更快。

    如果您使用的是 V2,则需要跳过 New-Object 的 -Property 参数,而是使用多次调用 Add-Member。它看起来像:

    $csv+=New-Object PSObject |
        Add-Member -Name program_code -Value $_.ProgramCode -MemberType NoteProperty -PassThru |
        Add-Member -Name first_name -Value $_.FirstName -MemberType NoteProperty -PassThru |
        ...
    

    【讨论】:

    • 谢谢,两个很好的解决方案!你需要少一点打字,这是我的忠实粉丝。
    • 使用 [pscustomobject]@{} 表示法极大地帮助了 v2 方法,谢谢
    【解决方案2】:

    按所需顺序选择字段,然后导出。

    $csv | select-object -property program_code,first_name,last_name,email,phone,phone2,address,address2,city,state,psotal_code,country,grad_year,lead_date,lead_source,school_status |
    Export-CSV C:\scripts\NewLeads$(Get-Date -Format yyyyMMdd).csv -notype -Append
    

    但是,您可以将其短路一点。根据$dataTable 的实际情况,您可能(在大多数情况下应该)能够直接从该对象中选择并绕过创建PSObjects 的集合。但是,如果您需要自定义标头,则需要在 select-object 中使用表达式(为了便于阅读而使用换行符)。

    $dataTable| select-object @{Name="program_code";Expression={$_.ProgramCode}},`
    @{Name="first_name";Expression={$_.firstname}},`
    @{Name="last_name";Expression={$_.lastname}},email,phone,`
    @{Name="phone2";Expression={$_.otherphone}},`
    @{Name="addr1";Expression={$_.address}},`
    @{Name="addr2";Expression={$_.address2}},city,state,`
    @{Name="postal_code";Expression={$_.zip}},country,`
    @{Name="grad_year";Expression={$_.hsgraddate}},`
    @{Name="lead_date";Expression={$_.leaddate}},`
    @{Name="lead_source";Expression={$_.leadsource}},`
    @{Name="school_status ";Expression={$_.schoolstatus }}|
     Export-CSV C:\scripts\NewLeads$(Get-Date -Format yyyyMMdd).csv -notype -Append
    

    【讨论】:

      最近更新 更多