powershellreplacenewlineeol

Replace CRLF using powershell


Editor's note: Judging by later comments by the OP, the gist of this question is: How can you convert a file with CRLF (Windows-style) line endings to a LF-only (Unix-style) file in PowerShell?

Here is my powershell script:

 $original_file ='C:\Users\abc\Desktop\File\abc.txt'
 (Get-Content $original_file) | Foreach-Object {
 $_ -replace "'", "2"`
-replace '2', '3'`
-replace '1', '7'`
-replace '9', ''`
-replace "`r`n",'`n'
} | Set-Content "C:\Users\abc\Desktop\File\abc.txt" -Force

With this code i am able to replace 2 with 3, 1 with 7 and 9 with an empty string. I am unable to replace the carriage return line feed with just the line feed. But this doesnt work.


Solution

  • You have not specified the version, I'm assuming you are using Powershell v3.

    Try this:

    $path = "C:\Users\abc\Desktop\File\abc.txt"
    (Get-Content $path -Raw).Replace("`r`n","`n") | Set-Content $path -Force
    

    Editor's note: As mike z points out in the comments, Set-Content appends a trailing CRLF, which is undesired. Verify with: 'hi' > t.txt; (Get-Content -Raw t.txt).Replace("`r`n","`n") | Set-Content t.txt; (Get-Content -Raw t.txt).EndsWith("`r`n"), which yields $True.

    Note this loads the whole file in memory, so you might want a different solution if you want to process huge files.

    UPDATE

    This might work for v2 (sorry nowhere to test):

    $in = "C:\Users\abc\Desktop\File\abc.txt"
    $out = "C:\Users\abc\Desktop\File\abc-out.txt"
    (Get-Content $in) -join "`n" > $out
    

    Editor's note: Note that this solution (now) writes to a different file and is therefore not equivalent to the (still flawed) v3 solution. (A different file is targeted to avoid the pitfall Ansgar Wiechers points out in the comments: using > truncates the target file before execution begins). More importantly, though: this solution too appends a trailing CRLF, which may be undesired. Verify with 'hi' > t.txt; (Get-Content t.txt) -join "`n" > t.NEW.txt; [io.file]::ReadAllText((Convert-Path t.NEW.txt)).endswith("`r`n"), which yields $True.

    Same reservation about being loaded to memory though.