Powershell 从CSV文件的字符串列中删除新行字符

Powershell 从CSV文件的字符串列中删除新行字符,powershell,csv,Powershell,Csv,我有一个CSV文件,其中有一个字符串列,该列跨越多行。我想把这些多行聚合成一行 比如说 1, "asdsdsdsds", "John" 2, "dfdhifdkinf dfjdfgkdnjgknkdjgndkng dkfdkjfnjdnf", "Roy" 3, "dfjfdkgjfgn", "Rahul" 我希望我的输出是 1, "asdsdsdsds", "John" 2, "dfdhifdkinf dfjdfgkdnjgknkdjgndkng dkfdkjfnjdnf", "Roy" 3,

我有一个CSV文件,其中有一个字符串列,该列跨越多行。我想把这些多行聚合成一行

比如说

1, "asdsdsdsds", "John"
2, "dfdhifdkinf
dfjdfgkdnjgknkdjgndkng
dkfdkjfnjdnf", "Roy"
3, "dfjfdkgjfgn", "Rahul"
我希望我的输出是

1, "asdsdsdsds", "John"
2, "dfdhifdkinf dfjdfgkdnjgknkdjgndkng dkfdkjfnjdnf", "Roy"
3, "dfjfdkgjfgn", "Rahul"
我希望使用PowerShell实现此输出


谢谢。

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

import-csv Before.csv -Header "ID","Change" | Select ID,@{Name="NoNewLines", Expression={$_.Change -replace "`n"," "}} | export-csv After.csv
关键部分在select语句中,它允许您传递一个专门的哈希表名称,即属性的名称,表达式是计算它的scriptblock

您可能需要稍微修改标题以获得所需的确切输出。

尝试以下方法:

$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',并用实际列名替换值

如果不希望字段周围有双引号,可以通过以下方式替换导出Csv来删除它们:

... | ConvertTo-Csv -NoTypeInformation | % { $_ -replace '"' } | Out-File $csv
要从输出中删除标头,请在输出文件之前添加另一个筛选器以跳过第一行:

... | select -Skip 1 | Out-File $csv

根据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

导出CSV有两个问题:

早期版本的powershell1和2不允许将数据附加到CSV 如果通过管道传输到其中的数据包含换行符,则该数据在Excel中无效 解决上述两个问题的方法是使用ConvertToCSV。以下是一个示例:

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

请注意,在这种情况下,这允许您对数据进行任何编辑,替换换行符数据,并使用redirecrors进行追加。

仅供参考:我创建了一个CSV清理器:

这可以用来替换任何不需要的字符/应该直接适应您的需要

代码复制如下;尽管我建议参考上面的帖子来查看其他人的反馈

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 ':' 

第2行第2列末尾缺少双引号是故意的还是打字错误?字符串可以包含逗号吗?输入错误…很抱歉。更正了!如何在PHP中实现它?除了上面的问题,我在每列上都有双引号。在同一个脚本中,如何用空白字符替换双引号?谢谢Ansgar!!一个小问题,有没有办法从CSV输出中删除标题?当我尝试在excel中打开新创建的CSV文件时,它只在一列中打开。如何解决这个问题?这将是一个新的问题,也是一个需要解决的问题。问题可能与文件的扩展名、选择的分隔符以及如何在Excel中打开文件有关。我不确定,但上面的命令无法从csv文件的一列中删除新行字符。