排序和导出CSV

时间:2016-08-23 12:14:43

标签: powershell

我有一个csv文件,其中包含以下提取的行:

  

“雇员”, “名字”, “姓氏”, “位置”, “部”, “TelephoneNo”, “电子邮件”
  “000001”,“abc”,“def”,“Loc1”,“”,“”,“name1@company.com”
  “000023”,“ghi”,“jkl”,“Loc2”,“”,“”,“name2@company.com”
  “000089”,“mno”,“pqr”,“Loc2”,“”,“”,“name3@company.com”

如何保留引号并排序并保存为csv文件?

我有以下的powershell源脚本,它适用于没有列的双引号的csv文件:

Get-Content $Source -ReadCount 1000 |
    ConvertFrom-Csv -Delimiter $Delimiter | 
    Sort-Object -Property $NamesOfColumns -Unique |
    ForEach-Object {
        # Each of the values in $ColumnValueFormat must be executed to get the property from the loop variable ($_). 
        $values = foreach ($value in $ColumnValueFormat) {
            Invoke-Expression $value
        }
        # Then the values can be passed in as an argument for the format operator.
        $ShowColsByNumber -f $values
    } | 
    Add-Content $Destination;

动态提供或构建$Source$Delimiter$NamesOfColumns$ColumnValueFormat

带有非引用csv文件的

$ColumnValueFormat包含:

$_.EmployeeID.Trim()
$_.FirstName.Trim()
$_.LastName.Trim()
$_.Location.Trim()
$_.Department.Trim()
$_.TelephoneNo.Trim()
$_.Email.Trim()
带有引用的csv文件的

$ColumnValueFormat包含:

$_."EmployeeID".Trim()
$_."FirstName".Trim()
$_."LastName".Trim()
$_."Location".Trim()
$_."Department".Trim()
$_."TelephoneNo".Trim()
$_."Email".Trim()

问题似乎是基于$ColumnValueFormat,它将列标题放在双引号中。 (如果我删除它们,我不确定cmdlet的内部在处理行时是否会识别列标题)

我遇到两个问题:

  1. 由双引号括起的列标题。问题似乎是基于$ColumnValueFormat,它将列标题放在双引号中,因为它不处理行。 (如果我删除双引号,则它在处理行时无法识别列标题。)
  2. 我在上一分钟遇到的另一个问题是,如果最后一列为空,则认为它是空的,而Invoke-Expression $value执行时($value保存最后一列$_.Email.Trim() - 在一个非引用的CSV文件上)它炸弹。如果我尝试将语句放在try / catch块中,它只是忽略它,最后一列没有添加到$values数组并再次发生炸弹。

1 个答案:

答案 0 :(得分:2)

属性名称周围的引号在语法上用于访问带空格的名称,而不是在输出中写引号。

Export-Csv cmdlet没有强制引号的选项,因此我们必须手动导出CSV。并且我们必须使用空字符串处理$Null之后ConvertFrom-Csv的空值。如果只需要某些字段,我们会将Select cmdlet与-index参数一起使用。

Get-Content $Source |
    ConvertFrom-Csv |
    %{ $header = $false } {
        if (!$header) {
            $header = $true
            '"' + (
                ($csv[0].PSObject.Properties.Name.trim() |
                    select -index 1,6
                ) -join '","'
            ) + '"'
        }
        '"' + (
            ($_.PSObject.Properties.Value |
                %{ if ($_) { $_.trim() } else { '' } } |
                select -index 1,6
            ) -join '","'
        ) + '"'
    } | Out-File $Destination

上述代码非常适合大型CSV文件的传递处理,因为它不会将整个文件保留在内存中。否则,可以稍微简化代码:

$csv = Get-Content $Source | ConvertFrom-Csv
$csv | %{
    '"' + (
        ($csv[0].PSObject.Properties.Name.trim() |
            select -index 1,6
        ) -join '","'
    ) + '"'
} {
    '"' + (
        ($_.PSObject.Properties.Value |
            %{ if ($_) { $_.trim() } else { '' } } |
            select -index 1,6
        ) -join '","'
    ) + '"'
) | Out-File $Destination