32

How do I prevent PowerShell's Out-File command from appending a newline after the text it outputs?

For example, running the following command produces a file with contents "TestTest\r\n" rather than just "TestTest".

"TestTest" | Out-File -encoding ascii test.txt
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Matt
  • 865
  • 2
  • 10
  • 16

3 Answers3

57

In PowerShell 5.0+, you would use:

"TestTest" | Out-File -encoding ascii test.txt -NoNewline

But in earlier versions you simply can't with that cmdlet.

Try this:

[System.IO.File]::WriteAllText($FilePath,"TestTest",[System.Text.Encoding]::ASCII)
briantist
  • 45,546
  • 6
  • 82
  • 127
  • 2
    Use append switch as well to avoid overwriting whole file .i.e "TestTest" | Out-File -encoding ascii test.txt -NoNewline -Append – Mohtisham Zubair Feb 03 '19 at 07:02
  • unfortunately WriteAllText always rewrites the target file, so it's not useful for continuous writing into log file. – McVitas May 25 '20 at 22:34
19

To complement briantist's helpful answer re -NoNewline:

The following applies not just to Out-File, but analogously to Set-Content / Add-Content as well; as stated, -NoNewline requires PSv5+.

Note that -NoNewline means that with multiple objects to output, it is not just a trailing newline (line break) that is suppressed, but any newlines.

In other words: The string representations of the input objects are directly concatenated, without a separator (terminator).

Therefore, the following commands result in the same file contents (TestTest without a trailing newline):

# Single input string
"TestTest" | Out-File -encoding ascii test.txt -NoNewline

# Equivalent command: 2-element array of strings that are directly concatenated.
"Test", "Test" | Out-File -encoding ascii test.txt -NoNewline

In order to place newlines only between, but not also after the output objects, you must join the objects with newlines explicitly:

"Test", "Test" -join [Environment]::NewLine |
  Out-File -encoding ascii test.txt -NoNewline

[Environment]::NewLine is the platform-appropriate newline sequence (CRLF on Windows, LF on Unix-like platforms); you can also produce either sequence explicitly, if needed, with "`r`n" and "`n"

Caveat:

The above -join solution implicitly converts the input objects to strings, if they aren't already and does so by calling the .NET .ToString() method on each object. This often yields a different representation than the one that Out-File would directly create, because Out-File uses PowerShell's default output formatter; for instance, compare the outputs of (Get-Date).ToString() and just Get-Date.

If your input comprises only strings and/or non-strings whose .ToString() representation is satisfactory, the above solution works, but note that it is then generally preferable to use the Set-Content cmdlet, which applies the same stringification implicitly.
For a complete discussion of the differences between Out-File and Set-Content, see this answer.

If your input has non-strings that do you want to be formatted as they would print to the console, there is actually no simple solution: while you can use Out-String to create per-object string representations with the default formatter, Out-String's lack of -NoNewline (as of v5.1; this GitHub issue suggests introducing it) would invariably yield trailing newlines.

mklement0
  • 382,024
  • 64
  • 607
  • 775
0

To complement briantist's and mklement0's helpful answers re -NoNewline:

I created this little function to replace the -NoNewLine parameter of Out-File in previous versions of powershell.

Note: In my case it was for a .csv file with 7 lines (Days of the week and some more values)

## Receive the value we want to add and "yes" or "no" depending on whether we want to 
put the value on a new line or not.
function AddValueToLogFile ($value, $NewLine) {
    ## If the log file exists:
    if (Test-path $Config.LogPath) {
        ## And we don't want to add a new line, the value is concatenated at the end.
        if ($NewLine -eq "no") {
            $file = Get-Content -Path $Config.LogPath 
            ## If the file has more than one line
            if ($file -is [array]) {
                $file[-1]+= ";" + $value
            }
            ## if the file only has one line
            else {
                $file +=  ";" + $value
            }
            $file | Out-File -FilePath $Config.LogPath
        }
        ## If we want to insert a new line the append parameter is used.
        elseif ($NewLine -eq "yes") {
            $value | Out-File -Append -FilePath $Config.LogPath
        }
    }
    ## If the log file does not exist it is passed as a value
    elseif (!(Test-path $Config.LogPath)) {
        $value | Out-File -FilePath $Config.LogPath
    }
}
Velaa98
  • 1
  • 1