37

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

4 Answers 4

63

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)
Sign up to request clarification or add additional context in comments.

2 Comments

Use append switch as well to avoid overwriting whole file .i.e "TestTest" | Out-File -encoding ascii test.txt -NoNewline -Append
unfortunately WriteAllText always rewrites the target file, so it's not useful for continuous writing into log file.
20

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.

Comments

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
    }
}

Comments

0

In case you want to write array of line to file without trailing newline, you can do as following:

# prepare content, 5 lines
$arrayOfLines = 1..5 | % { "line $_" }
# display
$arrayOfLines

# save all but the last one
$arrayOfLines | select -SkipLast 1 > .\newfile.txt
# save the last one, with -NoNewline
$arrayOfLines[-1] | out-file -NoNewline -Append .\newfile.txt 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.