替换ConvertTo-Csv cmdlet生成的字段周围的引号

3

我有一个用ConvertTo-Csv cmdlet导出的制表符分隔的csv文件。在导出时,它会将每个字段括在引号中。我试图仅删除这些引号(我不想删除字段中的引号)。我尝试了以下代码但未成功。

(Get-Content $root\$filename) | % {$_ -replace('"`t"', "`t")} | Set-Content $root\$filename

数值以这种方式打印,用制表符分隔:"MASSP"。如果是"M"ASSP",我想去掉外面的双引号,并保留字母"M"后面的引号。


2
出了什么问题?它是只错过了第一个引号,还是报错了,或者根本没有替换任何引号? - LinkBerest
该文件是在字段和字段名称周围仍带引号的情况下生成的。 - Patrick Mahoney
我认为你的意思是 "M""ASSP",而不是 "M"ASSP"ConvertTo-Csv 会将嵌入的双引号转义为 "" - mklement0
我指的是由转换为 CSV 生成的任何双引号。 - Patrick Mahoney
1个回答

4
尝试以下操作:
(Get-Content $root\$filename) |
  % { ($_ -replace '^"|"$|(?<=\t)"|"(?=\t)', '') -replace '""', '"' } |
    Set-Content $root\$filename

- 在问题中使用的-replace('"`t"', "`t")虽然在语法上可行,但它表明您错误地认为-replace需要方法语法来调用;然而,-replace是一个运算符
- 在正则表达式参数内部,由于您使用的是单引号字符串,因此适用正则表达式转义规则,所以制表符必须表示为\t
- 与我最初的想法不同,可以在单个管道中从文件读取和写入相同的文件,正如OP本人所演示的,并由Frode F.在评论中指出:将Get-Content $root\$filename封闭在括号中确保文件被一次性全部读取并立即关闭,允许Set-Content覆盖它。

该方法使用2个步骤:

  • 在第一步骤中,删除所有字段-起始和字段-结束双引号。
    • ^"匹配第一个字段的开头"
    • (?<=\t)"匹配任何字段的开头"但不是第一个。
    • "(?=\t)匹配任何字段的结尾引号,但不是最后一个。
    • "$匹配最后一个字段的结束"
  • 在第二步骤中,将所有字段-内部双引号(由ConvertTo-Csv 加倍)替换为单个实例。

谢谢mklement0,你的解决方案很有效!我从你们这里学到了很多。 - Patrick Mahoney
2
(Get-Content file.txt) | % { $_ } | Set-Content file.txt 这个命令是有效的。在 Get-Content 周围使用子/组表达式,这样它就会在将整个文件发送到管道之前读取整个文件。 - Frode F.
@FrodeF:谢谢,我忽略了这个 - 这是一个方便的技巧(虽然不适用于大文件);回答已更新。 - mklement0
3
说实话,“Get-content”不适用于大文件。 :-) - Frode F.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接