我需要替换几个子文件夹中文件中的 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-Content
和 Out-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/