Question:
I have a small powershell script which reads a document with UTF8 encoding, makes some replacements in it and saves it back which looks like this:
1 2 |
(Get-Content $path) -Replace "myregex","replacement" | Set-Content $path2 -Encoding utf8 |
This will create a new file with the right encoding and right contents but there are additional new line characters at the end. According to this answer and many others, I am told to either:
- Add the parameter
-NoNewLine
toSet-Content
- Use
[System.IO.File]::WriteAllText($path2,$content,[System.Text.Encoding]::UTF8)
Both solutions remove the trailing new lines… and every other new lines in the file.
Is there a way to both:
- Remove the trailing new lines while saving the file.
- Keep the existing new lines in my file.
Answer:
[IO.File]::WriteAllText()
assumes that $content
is a single string, but Get-Content
produces an array of strings (and removes the line breaks from the end of each line/string). Mangling that string array into a single string joins the strings using the $OFS
character (see here).
To avoid this behavior you need to ensure that $content
already is a single string when it’s passed to WriteAllText()
. There are various ways to do that, for instance:
- Use
Get-Content -Raw
(PowerShell v3 or newer):
12$content = (Get-Content $path -Raw) -replace 'myregex', 'replacement' - Pipe the output through
Out-String
:
1234$content = (Get-Content $path | Out-String) -replace 'myregex', 'replacement' -replace '\r\nNote, however, thatOut-String
(just likeSet-Content
) adds a trailing line break, as was pointed out in the comments. You need to remove that with a second replacement operation. - Join the array with the
-join
operator:
12$content = (Get-Content $path) -replace 'myregex', 'replacement' -join "`r`n"
Source:
How can I prevent additional newlines with set-content while keeping existing ones when saving in UTF8? by stackoverflow.com licensed under CC BY-SA | With most appropriate answer!
Note, however, that Out-String
(just like Set-Content
) adds a trailing line break, as was pointed out in the comments. You need to remove that with a second replacement operation.
-join
operator:
1 |