【问题标题】:PowerShell script to replace commas within double quotes with nothingPowerShell脚本来替换双引号内的逗号,什么都没有
【发布时间】:2017-06-29 14:51:12
【问题描述】:

我有一个逗号分隔的 CSV 文件,我打算将双引号中的逗号替换为空,并将双引号替换为空:

编者注:这个问题的原始形式要求“将[the]分隔符更改为管道”(|),它不再是要求; gms0ulman 的答案是在它还在的时候写的。

$inform = Get-Content C:\test.csv
$inform | % { 
$info = $_.ToString().Replace(",","") 
$var = $info 
$var | Out-file C:\test1.csv -Append 
}

任何帮助将不胜感激。

在:

1,2,"Test,ABC"

输出:

1,2,TestABC

【问题讨论】:

    标签: powershell csv


    【解决方案1】:

    我会将其分为两个步骤。另一个 StackOverflow 用户也许可以给你一个单行。

    Import-Csv C:\test.csv | Export-Csv tempfile.csv -Delimiter "|"
    (Get-Content tempfile.csv).Replace(",","").Replace('"',"") | Out-File test1.csv
    

    【讨论】:

    • @mklement0 我相信这是必需的,但 OP 已经在代码中完成了这部分工作。最初的问题指定分隔符从, 更改为|...我将它留在那里,因为我认为最好一次性完成,而不是像 OP 那样遍历文件。跨度>
    • 我明白了;无论最终意图如何,++ 都是一种聪明的方法(由于两次读取和写入文件,它会很慢,但这是否重要取决于用例)。除非您担心 PSv2 兼容性,否则您可以使用 Get-Content -Raw 加快速度;相反,如果文件太大而无法立即放入内存,请在ForEach 调用中执行.Replace 调用。更好的是,如果您使用 ConvertTo-Csv -NotypeInformation,则可以避免中间文件,如 Bacon Bits 的回答。
    【解决方案2】:

    导入 CSV。将其转换为具有不同分隔符的 CSV。替换逗号。将分隔符转换回来。替换双引号。写出生成的文件。

    Import-Csv -Path C:\MyFile.csv |
        ConvertTo-Csv -Delimiter '|' | 
        ForEach-Object { $_ -replace ',',[String]::Empty } | 
        ConvertFrom-Csv -Delimiter '|' | 
        ConvertTo-Csv |
        ForEach-Object { $_ -replace -replace '"',[String]::Empty } |
        Set-Content -Path C:\MyFile_fixed.csv
    

    【讨论】:

      【解决方案3】:

      您的 csv 是否有标题?要更改的值是否在同一列中?

      如果它看起来像这样:

      h1,h2,h3
      1,2,"Test,ABC"
      3,4,"Test,DEF"
      

      这应该可行:

      $Csv = Import-Csv -path C:\MyFile.csv
      $Csv.H3 | foreach {$_.Replace('"',"").Replace(",","")}
      

      编辑: 让它工作。但是和mklement0的解决方案基本一样

      $Csv = Import-Csv -path C:\MyFile.csv
      $Csv | Foreach {$_.H3 = $_.H3.Replace(",","")}
      $CsvObject = $Csv | Convertto-Csv -NoTypeInformation
      $CsvObject.replace('"','') | 
      Set-Content C:\OutFile.Csv
      

      【讨论】:

      • ++;也许您只是为了可读性而这样做,但请注意,使用收集所有结果的中间变量在内存中对于大文件是有问题的。您可以只使用一个管道,一次处理一个对象。 Quibble:$CsvObject 是一个不幸的变量名,因为它包含 字符串数组(行)。
      • 好点。我解决这个问题的方法是在创建 csv 文件之前尝试修复格式问题,但这可能会受到数据源的限制。有时似乎过度依赖 txt 文件、csv 文件等。这可能是 cmd 的后遗症。有趣的是,Import-Csv 生成一个对象,但 Convertto-Csv 生成字符串,乍一看似乎违反直觉。
      【解决方案4】:

      以下应该做你想做的(在 PSv5.1 中测试):

      Import-Csv C:\test.csv | ForEach-Object -Begin { $writeHeader = $True } {
        if ($writeHeader) { $writeHeader = $False; $_.psobject.properties.Name -join ',' }
        $_.psobject.properties.Value -replace ',', '' -join ','
      } | Set-Content -Encoding UTF8 test1.csv
      
      • Import-Csv 将您的 CSV 文件读入自定义对象([pscustomobject] 实例),其属性包含已删除双引号的列值。

        • 由于列值随后存储在不同的属性中,因此列-内部, 实例可以盲目替换,而无需担心列-分离, 实例。
        • 自动去除封闭的双引号是一个有益的副作用,但必须注意不要在输出中重新引入它们 - 请继续阅读。
      • 问题是您可以在修改对象后使用Export-Csv,因为它总是在所有输出值周围添加双引号(后退)。

      • 因此,必须为每个自定义对象执行自定义迷你脚本,使用ForEach-Object

        • -Begin { $writeHeader = $True }在开始时执行一次,表示需要在第一个数据行之前输出标题行。

        • $_.psobject.properties 是在输入对象上定义的所有属性的集合,以标题列命名,并包含给定数据行的值。

        • $_.psobject.properties.Name -join ',' 输出标题行,只需将属性名称(即列标题)与, 连接起来即可生成单个输出字符串。

        • $_.psobject.properties.Value -replace ',', '' 删除任何值内部的 , 实例(将它们替换为空字符串),-join ',' 再次将结果值与, 原样连接,输出数据行。

      • Set-Content - 这里比Out-File 更可取,因为输出对象已经是字符串 - 用于写入输出文件。

        • 注意-Encoding参数控制输出字符编码-根据需要调整。

        • Windows PowerShell(最高 v5.1 的版本)中,不使用 -Encoding 将默认使用系统的“ANSI”代码页(即使帮助主题声明 ASCII),而 @987654340 @ 将默认为 UTF-16LE(“Unicode”)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-18
        • 2014-12-06
        • 2015-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多