从 CSV 中的数字中删除逗号

Remove commas from numbers in a CSV

我有所有用户文件夹的文件夹信息。它被转储到 CSV 文件中,如下所示:

Servername, F:\Users\user, 9,355.7602 MB, 264, 3054, 03/15/2000 13:28:48, 12/10/2018 11:58:29

由于第 3 列中的千位分隔符,我们无法按原样处理数据。我可以再次 运行 报告脚本,但是我们有很多文件服务器,尤其是在其中一个服务器上有大量用户,因此再次 运行 非常耗时。有逗号的原因是数据是作为字符串而不是数字写入的。

我可以导入和转换,唯一的问题是任何超过 1000 的数字都是错误的,然后所有其他数据都少了 1 列。我想替换两个数字之间的任何逗号。使用 PowerShell 似乎并不难,但我找不到任何运气。

如果你假设数据列是逗号加space你的号码没有spaces,你可以使用-replace运算符。

$line = 'Servername, F:\Users\user, 9,355.7602 MB, 264, 3054, 03/15/2000 13:28:48, 12/10/2018 11:58:29'
$line -replace '(?<=\d),(?=\d)'

如果是从文件中读取数据,可以用Get-Content, replace your data, and update the file with Set-Content读取数据。

(Get-Content file.csv) -replace '(?<=\d),(?=\d)' | Set-Content file.csv

如果文件很大,您可以使用更快的 switch 语句。

$data = switch -regex -file file.csv {
          '(?<=\d),(?=\d)' { $_ -replace '(?<=\d),(?=\d)' }
          default {$_}
        }
$data | Set-Content file.csv

解释:

  • (?<=\d) 使用匹配单个数字 \d.
  • 的正后向断言 (?<=)
  • (?=\d) 使用匹配单个数字的肯定前瞻断言 (?=)。您可以将其替换为 (?=\d{3}) 以匹配逗号后的 3 个连续数字。
  • 由于要将目标逗号替换为空字符串,因此不需要替换字符串。

通常,最好坚持使用处理 CSV 数据或文件的命令。但是,如果您的数据包含逗号并且您没有限定您的文本,则可能很难区分数据和分隔符。如果您有明确的区分方法,最好对文件使用 ConvertFrom-Csv for already read data or Import-Csv。您需要在文件或命令中定义 headers。

编辑

我疏忽了数据集中的 , 未分隔,这导致此答案无法按预期工作,因为在解析 CSV 时逗号被视为列分隔符。我将保留它,因为它确实解释了如果列数据被转义 属性,通常如何按照您的预期操作数据。但是,@AdminOfThings' answer below 应该适用于此处的特定情况,并且将修复错误定义的列,而不依赖于先将 CSV 内容解析为 CSV。


使用 Import-Csv 导入数据,然后删除第三列中的任何 ,。这假设您没有任何值,其中 , 是小数点分隔符:

如果 CSV 中有 header,则无需定义 header 名称或花时间写回 CSV:

Import-Csv -Path \path\to\file.csv | Foreach-Object {
  $_.ColumnName = $_.ColumnName -replace ','
} | Export-Csv -NoTypeInformation -Path \path\to\file.csv

其工作方式是我们将 CSV 导入为可操作的 PSCustomObject,然后对于每一行,我们采用具有大小的任何列名称并从中删除 ,。最后,我们将修改后的 PSCustomObject 导出回原始 CSV。

如果你没有 headers,它会变得有点棘手,因为我们必须定义临时 headers,但 Export-Csv 没有跳过的选项写出 headers:

Import-Csv -Path \path\to\file.csv -Headers Col1, Col2, Col3, Col4, Col5, Col6, Col7 |
  Foreach-Object {
    $_.Col3 = $_.Col3 -replace ','
  } | ConvertTo-Csv | Select-Object -Skip 1 |
  Set-Content -Path \path\to\file.csv

这与第一段代码的作用相同,但由于我们不想导出临时的 header,所以我们必须发挥创意。首先,请注意我们使用临时 header 名称引用目标列。我们首先要使用 ConvertTo-Csv 将 object 转换为 CSV,而不是将修改后的 CSV object 直接传输到 Export-Csv。然后我们使用 Select-Object 跳过转换后的 CSV 文本的第一行,即 header,所以我们只有行数据和列值。最后,我们使用 Set-Content 将没有 header 的 CSV 文本写回原始文件。