PowerShell脚本将双引号内的逗号替换为零
我有一个逗号分隔的CSV文件,我打算将双引号中的逗号替换为零,并将双引号替换为零: 编者按:此问题的原始形式要求“将[分隔符]更改为管道”(PowerShell脚本将双引号内的逗号替换为零,powershell,csv,Powershell,Csv,我有一个逗号分隔的CSV文件,我打算将双引号中的逗号替换为零,并将双引号替换为零: 编者按:此问题的原始形式要求“将[分隔符]更改为管道”(|),这不再是要求;gms0ulman的答案是在它还没有写完的时候写的 任何帮助都将不胜感激 在: 输出: 我将把它分解为两个步骤。另一个StackOverflow用户可能会给您一行 Import-Csv C:\test.csv | Export-Csv tempfile.csv -Delimiter "|" (Get-Content tempfile.cs
|
),这不再是要求;gms0ulman的答案是在它还没有写完的时候写的
任何帮助都将不胜感激
在:
输出:
我将把它分解为两个步骤。另一个StackOverflow用户可能会给您一行
Import-Csv C:\test.csv | Export-Csv tempfile.csv -Delimiter "|"
(Get-Content tempfile.csv).Replace(",","").Replace('"',"") | Out-File test1.csv
以下内容应满足您的要求(在PSv5.1中测试):
将您的Csv文件读取到自定义对象(Import Csv
实例)中,这些对象的属性包含已删除双引号的列值[pscustomobject]
- 由于列值随后存储在不同的属性中,因此可以盲目地替换列内部
实例,而不必担心列分隔,
实例,
- 封闭的双引号被自动剥离是一个有益的副作用,尽管必须注意不要在输出读取时重新引入它们
- 由于列值随后存储在不同的属性中,因此可以盲目地替换列内部
- 问题是在修改对象后不能使用
,因为它总是在所有输出值周围添加双引号(返回)导出Csv
- 因此,必须使用
,为每个自定义对象执行自定义迷你脚本:ForEach对象
在开始时执行一次,表示需要在第一个数据行之前输出头行-Begin{$writeHeader=$True}
是输入对象上定义的所有属性的集合,以标题列命名,并包含给定数据行的值$\u.psobject.properties
输出标题行,只需将属性名称(列标题)与$\pObject.properties.Name-join',
连接,以生成单个输出字符串,
删除任何内部值$.psobject.properties.Value-replace',“
实例(将其替换为空字符串)和,
再次按原样连接结果值,输出数据行-join',”
-这比此处的设置内容
更可取,因为输出对象已经是字符串-用于写入输出文件输出文件
- 注意
参数以控制输出字符编码-根据需要进行调整-Encoding
- 在Windows PowerShell(v5.1之前的版本)中,不使用
将默认为系统的“ANSI”代码页(即使帮助主题声称使用ASCII),而-Encoding
将默认为UTF-16LE(“Unicode”)Out File
- 注意
- 您的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
导入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
@我认为这是必需的,但OP已经在代码中完成了这一部分。原始问题指定分隔符从
,
更改为|
。。。我把它放在那里,因为我认为最好一次完成,而不是像OP那样遍历文件;无论最终目的是什么,++都是一种聪明的方法(由于读写文件两次,速度会很慢,但这是否重要取决于用例)。除非您担心PSv2的兼容性,否则您可以使用Get Content-Raw
;相反,如果文件太大,无法立即放入内存,请在ForEach
调用中执行.Replace
调用。更好的是,如果使用converttocsv-NotypeInformation
,就可以避免使用中间文件,如Bacon Bits的答案所示;也许您这样做只是为了可读性,但请注意,使用在内存中收集所有结果的中间变量对于大型文件是有问题的。您可以只使用单个管道,一次处理一个对象。狡辩:$CsvObject
是一个不幸的变量名,因为它包含一个字符串(行)数组。很好。我解决这个问题的方法是在创建csv文件之前尝试解决格式问题,但这可能会受到数据源的限制。有时似乎过度依赖txt文件、csv文件等。这可能是cmd的后遗症。有趣的是,导入Csv会生成一个对象,但Convertto Csv会生成字符串,乍一看似乎是违反直觉的。请允许我向新手提供标准建议:如果答案解决了您的问题,请单击大复选标记接受它(✓) 在它旁边,也可以选择向上投票(向上投票需要至少15个信誉点)。如果你发现其他答案有帮助,请向上投票。接受(你将获得2个信誉点)和向上投票有助于未来的读者。请参阅。
h1,h2,h3
1,2,"Test,ABC"
3,4,"Test,DEF"
$Csv = Import-Csv -path C:\MyFile.csv
$Csv.H3 | foreach {$_.Replace('"',"").Replace(",","")}
$Csv = Import-Csv -path C:\MyFile.csv
$Csv | Foreach {$_.H3 = $_.H3.Replace(",","")}
$CsvObject = $Csv | Convertto-Csv -NoTypeInformation
$CsvObject.replace('"','') |
Set-Content C:\OutFile.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