从CSV中的数字中删除逗号

时间:2019-11-18 21:39:08

标签: powershell csv comma text-manipulation digit-separator

我有所有用户文件夹的文件夹信息。如下所示将其转储到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似乎没有那么困难,但是我发现任何东西都没有运气。

2 个答案:

答案 0 :(得分:3)

如果您假设数据列之间用 逗号加空格 分隔并且 您的数字没有空格 ,您可以为此使用-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读取数据,替换数据,并使用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处理已读取的数据或使用Import-Csv处理文件。您将需要在文件或命令中定义标题。

答案 1 :(得分:0)

编辑

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


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

如果CSV中包含标头,则无需定义标头名称,也不需要花点时间写回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。

如果您没有标题,则由于我们必须定义临时标题而变得有些棘手,但是Export-Csv没有选择跳过标题的选项:

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

这与第一段代码的功能相同,但是由于我们不想导出临时标头,因此我们必须发挥创意。首先,请注意我们使用临时标题名称引用目标列。首先,我们不想使用Export-Csv将修改后的CSV对象直接传递给ConvertTo-Csv,而是将其转换为CSV。然后,我们使用Select-Object来跳过转换后的CSV文本的第一行,即标题,因此我们只有行数据和列值。最后,我们使用Set-Content将不带标题的CSV文本写回到原始文件。