【问题标题】:Remove comma in a field but not delimeter in powershell when not all values are in commas当并非所有值都在逗号中时,删除字段中的逗号但不删除 powershell 中的分隔符
【发布时间】:2017-05-17 04:26:20
【问题描述】:

我收到一个 CSV 文件,其中某些字段的某些记录中有逗号。因此,当我在记事本中打开文件时,一行如下所示

1,John,Wayne,"movies,actor",1950s

我已经争先恐后地编写语法来删除上面示例中第 4 列中电影和演员之间的逗号并将其替换为空格。然后再次将文件输出为 CSV。

这是我下面的内容,它将整个字符串“movies,actor”替换为空格。

(Get-Content $path) -replace '(".*),(.*")',' ' | Out-File -Encoding UTF8 $newpath

如何只用空格替换逗号?

【问题讨论】:

    标签: powershell csv


    【解决方案1】:

    因此,您可以尝试编写正则表达式来去除逗号,但我倾向于将其拆分为可支持性并便于修改其他字段。

    $csv = import-csv C:\Old.csv
    $NewCSV = @()
    
    Foreach($row in $csv)
    {
        $Object = New-Object -TypeName PSObject
        $Object | Add-Member -Type NoteProperty -Name "ID" -Value $csv.ID
        $Object | Add-Member -Type NoteProperty -Name "First" -Value $csv.First
        $Object | Add-Member -Type NoteProperty -Name "Last" -Value $csv.Last
        $Object | Add-Member -Type NoteProperty -Name "Desc" -Value $csv.Desc -replace ","," "
        $Object | Add-Member -Type NoteProperty -Name "Year" -Value $csv.Year
        $NewCSV += $Object
    }
    
    $NewCSV | Export-Csv C:\New.csv
    
    • 导入 csv
    • 创建一个新对象,用 $csv 中的行填充它
    • 当我们将每一行添加到 NewCSV 时,我们会替换逗号
    • 导出 NewCSV 对象

    它看起来很复杂,但您几乎可以使用管道将其压缩成一行

    $csv | % { $_.Desc = $_.Desc -replace ","," "; $_ | Export-Csv C:\New.csv -Append -NoClobber}

    【讨论】:

    • 喜欢正则表达式,但对我来说这是最强大的、面向未来的解决方案。
    • @LievenKeersmaekers 正则表达式是一个强大的工具,可以解决您的问题,或者如果您没有正确编写它,它会锁定您的整个应用程序。这些其他答案中所做的假设清楚地说明了为什么针对每个问题跳到正则表达式会导致问题发生。
    【解决方案2】:

    您实际上可以使用 -replace 来简单得多。替换时可以直接引用捕获组如下:

    (Get-Content $path) -replace '"(.*?),(.*?)"','$1 $2'
    

    它与 OP 解决方案非常相似,不同之处在于您创建了两个仅包含单词而不是引号的捕获组。然后这两个值在替换字符串中直接引用为 $1 和 $2 。

    【讨论】:

    • 这适用于 OP 发布的内容,但迟早会中断。如果文件包含1,John,Wayne,"movies,actor","1950s" 之类的内容。您可以通过使用非贪婪搜索进行调整,但我非常有信心有人可以提出一个也会破坏它的输入。最后,最强大的解决方案是 Nick 发布的。
    • 我非常有信心我可以提出一个也会打破尼克斯的意见:) 但我同意你的观点。假设这是唯一可以包含多个值的字段,更改为非贪婪或单词匹配将相当容易地解决这个问题。但是,如果需要一个解决方案来解决所有其他字段中可能出现的引号和逗号,那么就需要一个完全不同的解决方案。
    • @MarkJakobsen 您在这里假设 OP 可以从 csv 中的每一列中删除逗号,即使 OP 将第 4 列声明为他希望从中删除逗号的列。
    • @Nick 你是对的,鉴于第一行说明“某些字段的一些记录”,我认为第 4 列的具体问题只是问题的一个例子,而不是唯一的它可能发生的地方。我绝对可能是错的,但是做一个非贪婪的搜索和替换都可以。
    • @LievenKeersmaekers 绝对同意,尽管我很确定我的老板会称之为我的问题:D CSV 文件在我的经验中总是很困难。格式化很大程度上取决于创建和使用服务。
    【解决方案3】:

    我们可以使用正则表达式在线完成此操作,如下所示:

    (Get-Content D:\dummycsv.csv) | %{if($_ -match '(".*),(.*")'){$_ -replace $matches[0],($matches[1]+' '+$matches[2]);$_}}
    

    我正在匹配正则表达式并利用您与$matches 变量一起使用的匹配组

    【讨论】:

    • 请参阅我的答案底部,了解我将答案压缩为一行的位置。它更短、更容易阅读、更高效。您根本不需要弄乱匹配变量和 if 语句。你把事情复杂化了。
    • @Nick 错过了,我的错,但我相信你的 oneliner 仍然需要创建 $csv 对象。让 OP 决定哪个适合他
    • 它确实需要它,是的,添加它很简单。这不是我希望人们阅读和理解的免费服务代码。例如,您的一个班轮不像我的那样包含导出的 csv。
    猜你喜欢
    • 2019-02-12
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    相关资源
    最近更新 更多