Reputation: 967
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
Upvotes: 37
Views: 46923
Reputation: 1099
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
Upvotes: 0
Reputation: 437090
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.
Upvotes: 20
Reputation: 1
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
}
}
Upvotes: 0
Reputation: 47772
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)
Upvotes: 63