PowerShell v5+ supports the -NoNewline
switch with the Set-Content
cmdlet (and also Add-Content
and Out-File
).
If you're running an earlier version, you must use the .NET Framework directly, as demonstrated in one of the answers you link to.
Caveat: -NoNewline
doesn't just mean that a trailing newline is omitted, but that all input objects are concatenated directly, without a separator (and without adding a trailing newline).
If your input is a single multi-line string, as below, -NoNewLine
will work as expected, but if you have an array of strings you want to write with newlines only between them and not also a trailing one, you'll have to do something like:
(('one', 'two', 'three') -join "`n") + "`n" | Set-Content -NoNewLine $filePath
).
See also: this answer of mine.
As an aside: There's no need for multiple ForEach-Object
calls or even a foreach
statement; you can do it all in one pipeline (PSv3+, due to Get-Content -Raw
, but you can omit -Raw
to make it work (less efficiently) in PSv2 too):
Get-ChildItem . *.xml -Recurse |
ForEach-Object {
$filePath = $_.FullName
(Get-Content -Raw $filePath) -replace '&# 8211;', '–' `
-replace '&# 160;', ' ' `
-replace '&# 8221;', '”' |
Set-Content -NoNewline $filePath
}
Optional reading:
TheMadTechnician points out that an alternative to defining variable $filePath
to refer to the full path of the input file at hand inside the script block of the ForEach-Object
call is to use common parameter -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
}
Note how the argument passed to PipelinVariable
must not have the $
prefix, because it is the name of the variable to bind.
$ThisFile
then refers to Get-ChildItem
's current output object in all subsequent pipeline segment(s).
While there's not much to be gained in this particular case, the general advantage of using
-PipelinVariable
is that the variable bound this way can be referenced in any subsequent pipeline segment.