This is a state-of-the-union answer as of Windows PowerShell v5.1 / PowerShell Core v6.2.0:
Andrew Savinykh's ill-fated answer, despite being the accepted one, is, as of this writing, fundamentally flawed (I do hope it gets fixed - there's enough information in the comments - and in the edit history - to do so).
Ansgar Wiecher's helpful answer works well, but requires direct use of the .NET Framework (and reads the entire file into memory, though that could be changed). Direct use of the .NET Framework is not a problem per se, but is harder to master for novices and hard to remember in general.
A future version of PowerShell Core will have a
Convert-TextFile
cmdlet with a -LineEnding
parameter to allow in-place updating of text files with a specific newline style, as being discussed on GitHub.
In PSv5+, PowerShell-native solutions are now possible, because Set-Content
now supports the -NoNewline
switch, which prevents undesired appending of a platform-native newline[1]
:
# Convert CRLFs to LFs only.
# Note:
# * (...) around Get-Content ensures that $file is read *in full*
# up front, so that it is possible to write back the transformed content
# to the same file.
# * + "`n" ensures that the file has a *trailing LF*, which Unix platforms
# expect.
((Get-Content $file) -join "`n") + "`n" | Set-Content -NoNewline $file
The above relies on Get-Content
's ability to read a text file that uses any combination of CR-only, CRLF, and LF-only newlines line by line.
Caveats:
You need to specify the output encoding to match the input file's in order to recreate it with the same encoding. The command above does NOT specify an output encoding; to do so, use -Encoding
; without -Encoding
:
The input file's content as well as its transformed copy must fit into memory as a whole, which can be problematic with large input files.
There's a risk of file corruption, if the process of writing back to the input file gets interrupted.
[1] In fact, if there are multiple strings to write, -NoNewline
also doesn't place a newline between them; in the case at hand, however, this is irrelevant, because only one string is written.