我需要替换几个子文件夹中文件中的 HTML 实体,因此我使用了此处建议的 PowerShell 脚本:https://stackoverflow.com/a/2837891

但是,该脚本在文件末尾添加了一个额外的新行,我想避免这种情况。在该线程( https://stackoverflow.com/a/2837887 )的下一个评论中列出了另一个脚本,它应该完全满足我的需求,但是当我尝试运行它时它不起作用。

这是我的脚本:

$configFiles = Get-ChildItem . *.xml -rec
foreach ($file in $configFiles)
{
    (Get-Content $file.PSPath) |
    Foreach-Object { $_ -replace '&# 8211;','–' } |
    Foreach-Object { $_ -replace '&# 160;',' ' } |
    Foreach-Object { $_ -replace '&# 8221;','”' } |
    Set-Content $file.PSPath
}

我需要做的就是不要在最后添加新行。

先感谢您!

最佳答案

PowerShell v5+ 支持 -NoNewline 开关与 Set-Content cmdlet(以及 Add-ContentOut-File )。

如果您运行的是早期版本,则必须直接使用 .NET Framework,如 one of the answers you link to 中所示。

警告 : -NoNewline 不仅仅意味着省略了尾随换行符,而是所有输入对象都直接连接,没有分隔符(并且不添加尾随换行符)。
如果您的输入是单个多行字符串,如下所示,-NoNewLine 将按预期工作,但是如果您有一个字符串数组,您只想在它们之间使用换行符而不是尾随一个,则必须这样做就像是:(('one', 'two', 'three') -join "`n") + "`n" | Set-Content -NoNewLine $filePath )。
另请参阅:我的 this answer

顺便说一句: 不需要多个 ForEach-Object 调用 甚至 foreach 语句;您可以在一个管道中完成所有操作(PSv3+,由于 Get-Content -Raw ,但您也可以省略 -Raw 以使其在 PSv2 中工作(效率较低)):

Get-ChildItem . *.xml -Recurse |
  ForEach-Object {
    $filePath = $_.FullName
    (Get-Content -Raw $filePath) -replace '&# 8211;', '–' `
       -replace '&# 160;', ' ' `
          -replace '&# 8221;', '”' |
            Set-Content -NoNewline $filePath
  }

可选读物:

TheMadTechnician 指出,定义变量 $filePath 以引用 ForEach-Object 调用的脚本块内手头输入文件的完整路径的替代方法是使用公共(public)参数 -PipelineVariable ( -pv ):

Get-ChildItem . *.xml -Recurse -PipelineVariable ThisFile |
  ForEach-Object {
    (Get-Content -Raw $ThisFile.FullName) -replace '&# 8211;', '–' `
       -replace '&# 160;', ' ' `
          -replace '&# 8221;', '”' |
            Set-Content -NoNewline $ThisFile.FullName
  }

注意传递给 PipelinVariable 的参数不能有 $ 前缀,因为它是要绑定(bind)的变量的名称。$ThisFile 然后在所有后续管道段中引用 Get-ChildItem 的当前输出对象。

虽然在这种特殊情况下没有什么好处,但使用的一般优势-PipelinVariable 是这样绑定(bind)的变量可以在任何后续管道段中引用。

关于powershell - 防止 Powershell 在文件末尾添加新行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43402501/

10-09 01:59
查看更多