6

我有一个带有字符串列的 CSV 文件,该列跨越多行。我想将这些多行聚合为一行。

例如

1, "asdsdsdsds", "John"
2, "dfdhifdkinf
dfjdfgkdnjgknkdjgndkng
dkfdkjfnjdnf", "Roy"
3, "dfjfdkgjfgn", "Rahul"

我希望我的输出是

1, "asdsdsdsds", "John"
2, "dfdhifdkinf dfjdfgkdnjgknkdjgndkng dkfdkjfnjdnf", "Roy"
3, "dfjfdkgjfgn", "Rahul"

我想使用 PowerShell 实现此输出

谢谢。

4

5 回答 5

4

基于 Ansgar 的回答,以下是在以下情况下的操作方法:

  • 你不知道列名
  • 您的 CSV 文件可能单独包含 CR 或 LF

    (Import-Csv $csvInput) | % {
        $line = $_
        foreach ($prop in $line.PSObject.Properties) {
            $line.($prop.Name) = ($prop.Value -replace '[\r\n]',' ')
        }
        $line
    } | Export-Csv $csvOutput -NoTypeInformation
    
于 2014-03-24T00:30:56.597 回答
3

尝试这个:

$csv = 'C:\path\to\your.csv'

(Import-Csv $csv -Header 'ID','Value','Name') | % {
  $_.Value = $_.Value -replace "`r`n",' '
  $_
} | Export-Csv $csv -NoTypeInformation

如果您的 CSV 包含标题,请-Header 'ID','Value','Name'从导入中删除并替换Value为实际的列名。

如果您不想在字段周围使用双引号,则可以通过替换为以下内容来删除它们Export-Csv

... | ConvertTo-Csv -NoTypeInformation | % { $_ -replace '"' } | Out-File $csv

要从输出中删除标题,请在Out-File跳过第一行之前添加另一个过滤器:

... | select -Skip 1 | Out-File $csv
于 2013-09-04T17:55:10.280 回答
1

您可以导入 csv,进行专门的选择,然后将结果写入新的 CSV。

import-csv Before.csv -Header "ID","Change" | Select ID,@{Name="NoNewLines", Expression={$_.Change -replace "`n"," "}} | export-csv After.csv

关键部分在 select 语句中,它允许您传递专门的哈希表(Name 是属性的名称,Expression 是计算它的脚本块)。

您可能需要稍微摆弄标题才能获得所需的确切输出。

于 2013-09-04T17:37:41.010 回答
0

Export-CSV 的问题是双重的:

  • 早期版本(powershell1 和 2)不允许您将数据附加到 CSV
  • 如果传送给它的数据包含换行符,则数据在 Excel 中无用

上述两种情况的解决方案是改用 Convertto-CSV。这是一个示例:

{bunch of stuff} | ConvertTo-CSV | %{$_ -replace "`n","<NL>"} | %{$_ -replace "`r","<CR>"} >>$AppendFile

请注意,这允许您对数据进行任何编辑(在这种情况下,替换换行数据),并使用重定向器进行追加。

于 2014-11-19T18:23:34.233 回答
0

仅供参考:我创建了一个 CSV Cleaner:https ://stackoverflow.com/a/32016543/361842

这可用于替换任何不需要的字符/应该直截了当以适应您的需求。

代码复制如下;虽然我建议参考上述线程以查看其他人的任何反馈。

clear-host
[Reflection.Assembly]::LoadWithPartialName("System.IO") | out-null
[Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic") | out-null

function Clean-CsvStream {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline=$true)]
        [string]$CsvRow
        ,
        [Parameter(Mandatory = $false)]
        [char]$Delimiter = ','
        ,
        [Parameter(Mandatory = $false)]
        [regex]$InvalidCharRegex 
        ,
        [Parameter(Mandatory = $false)]
        [string]$ReplacementString 

    )
    begin {
        [bool]$IsSimple = [string]::IsNullOrEmpty($InvalidCharRegex) 
        if(-not $IsSimple) {
            [System.IO.MemoryStream]$memStream = New-Object System.IO.MemoryStream
            [System.IO.StreamWriter]$writeStream = New-Object System.IO.StreamWriter($memStream)
            [Microsoft.VisualBasic.FileIO.TextFieldParser]$Parser = new-object Microsoft.VisualBasic.FileIO.TextFieldParser($memStream)
            $Parser.SetDelimiters($Delimiter)
            $Parser.HasFieldsEnclosedInQuotes = $true
            [long]$seekStart = 0
        }
    }
    process {
        if ($IsSimple) {
            $CsvRow
        } else { #if we're not replacing anything, keep it simple
            $seekStart = $memStream.Seek($seekStart, [System.IO.SeekOrigin]::Current) 
            $writeStream.WriteLine($CsvRow)
            $writeStream.Flush()
            $seekStart = $memStream.Seek($seekStart, [System.IO.SeekOrigin]::Begin) 
            write-output (($Parser.ReadFields() | %{$_ -replace $InvalidCharRegex,$ReplacementString }) -join $Delimiter)
        }
    }
    end {
        if(-not $IsSimple) {
            try {$Parser.Close(); $Parser.Dispose()} catch{} 
            try {$writeStream.Close(); $writeStream.Dispose()} catch{} 
            try {$memStream.Close(); $memStream.Dispose()} catch{} 
        }
    }
}
$csv = @(
    (new-object -TypeName PSCustomObject -Property @{A="this is regular text";B="nothing to see here";C="all should be good"}) 
    ,(new-object -TypeName PSCustomObject -Property @{A="this is regular text2";B="what the`nLine break!";C="all should be good2"}) 
    ,(new-object -TypeName PSCustomObject -Property @{A="this is regular text3";B="ooh`r`nwindows line break!";C="all should be good3"}) 
    ,(new-object -TypeName PSCustomObject -Property @{A="this is regular text4";B="I've got;a semi";C="all should be good4"}) 
    ,(new-object -TypeName PSCustomObject -Property @{A="this is regular text5";B="""You're Joking!"" said the Developer`r`n""No honestly; it's all about the secret VB library"" responded the Google search result";C="all should be good5"})
) | convertto-csv -Delimiter ';' -NoTypeInformation
$csv | Clean-CsvStream -Delimiter ';' -InvalidCharRegex "[`r`n;]" -ReplacementString ':' 
于 2015-08-14T18:32:50.690 回答