在以UTF8保存时,如何在保留现有内容的同时阻止使用set-content的其他换行符?

时间:2017-05-02 15:44:11

标签: powershell utf-8

我有一个小的PowerShell脚本,它使用UTF8编码读取文档,在其中进行一些替换并将其保存回来,如下所示:

(Get-Content $path) -Replace "myregex","replacement" | Set-Content $path2 -Encoding utf8

这将创建一个具有正确编码和正确内容的新文件,但最后还有其他新行字符。根据{{​​3}}和其他许多人的说法,我被告知要么:

  1. 将参数-NoNewLine添加到Set-Content
  2. 使用[System.IO.File]::WriteAllText($path2,$content,[System.Text.Encoding]::UTF8)
  3. 两种解决方案都会移除尾随的新行... 以及文件中的所有其他新行

    有没有办法两个

    1. 保存文件时删除尾随的新行。
    2. 将现有新行保留在我的文件中。

2 个答案:

答案 0 :(得分:3)

[IO.File]::WriteAllText()假设$content是单个字符串,但Get-Content生成一个字符串数组(并从每个行/字符串的末尾删除换行符)。将字符串数组迁移到单个字符串中使用$OFS字符连接字符串(请参阅here)。

要避免此行为,您需要确保$content在传递给WriteAllText()时已经是单个字符串。有多种方法可以做到这一点,例如:

  • 使用Get-Content -Raw(PowerShell v3或更高版本):

    $content = (Get-Content $path -Raw) -replace 'myregex', 'replacement'
    
  • 通过Out-String

    管道输出
    $content = (Get-Content $path | Out-String) -replace 'myregex', 'replacement' -replace '\r\n$'
    

    但请注意,Out-String(就像Set-Content)会添加一个尾随换行符,正如评论中所指出的那样。您需要通过第二次更换操作将其删除。

  • 使用-join运算符加入数组:

    $content = (Get-Content $path) -replace 'myregex', 'replacement' -join "`r`n"
    

答案 1 :(得分:3)

补充Ansgar Wiechers' helpful answer

使用 Set-Content -NoNewline(PSv5 +)是一个选项,但前提是您将输出作为带有嵌入换行符的字符串传递Get-Content -Raw可以做到:

(Get-Content -Raw $path) -replace 'myregex', 'replacement' |  
  Set-Content -NoNewline $path2 -Encoding utf8

但请注意-replace的语义随-Raw的变化而变化:现在是
对{em>多行字符串(整个文件内容)执行-replace操作 - 而不是使用数组作为LHS的行个别操作。< / p>

另请注意,-Raw将保留输入的尾随换行或无状态。

如果你想要逐行语义和/或想要确保输出的最后一行没有尾随换行符(即使输入文件只有一行),请使用Get-Content而不{ {1}},然后-Raw

-join

以上在输出中使用适合平台的换行符,但请注意,输入文件不能保证使用相同的字符。

至于您尝试的内容

正如您所观察到的那样,带有数组字符串的 (Get-Content $path) -replace 'myregex', 'replacement' -join [Environment]::NewLine | Set-Content -NoNewline $path2 -Encoding utf8 会导致所有字符串连接而没有分隔符 - 与预期的不同,Set-Content -NoNewline并不会省略尾随换行符:

-NoNewline

注意:输入字符串中的换行符 embedded 会被保留。

> 'one', 'two' | Set-Content -NoNewline t.txt; Get-Content -Raw t.txt onetwo # Strings were directly concatenated. 方法导致任何换行符的原因不同,正如Ansgar的回答中所述。