Udostępnij za pośrednictwem


PowerShell gotcha of the day: set-content adds newlines by default

In a script I was writing, I was using set-content to put a particular string (just one string) into a file.  The file was consistently 2 bytes longer than I expected.  Since it was adding a newline, I asked how I could get it to not add the newline since I didn't want the added new line in my file.

Here's a quick example shows that in action:

 C:\temp > $str = 'string'
C:\temp > $file = 'c:\temp\x'
C:\temp > [io.file]::writealltext($file, $str)
C:\temp > (dir $file).length
6
C:\temp > format-hex x

Address:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F 10 11 12 13 14 15 16 17 ASCII
-------- ----------------------------------------------------------------------- ------------------------
00000000 73 74 72 69 6E 67                                                       string
C:\temp > set-content $file $str
C:\temp > (dir $file).length
8
C:\temp > format-hex x

Address:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F 10 11 12 13 14 15 16 17 ASCII
-------- ----------------------------------------------------------------------- ------------------------
00000000 73 74 72 69 6E 67 0D 0A                                                 string..
C:\temp >

Lee responded that this was a good default behavior (and I agree) because it lets you set-content with arrays of strings and get them one per line.

 [C:\temp]
PS:101 > Set-Content c:\temp\foo.txt "Hello","World"
Suggestion: An alias for Set-Content is sc

[C:\temp]
PS:102 > gc c:\temp\foo.txt
Hello
World

Lee also provided a workaround for my particular situation - get the byte encoding so we're not using the filesystem provider's WriteLine calls to send strings to a file.

 
 [C:\temp]
PS:99 > Set-Content c:\temp\foo.txt ([byte[]][char[]] "Hello") -Encoding Byte
Suggestion: An alias for Set-Content is sc

[C:\temp]
PS:100 > format-hex c:\temp\foo.txt

Address:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F 10 11 12 13 14 15 16 17 ASCII
-------- ----------------------------------------------------------------------- ------------------------
00000000 48 65 6C 6C 6F                                                          Hello

Admittedly, it's much easier for me to just use System.IO.File's WriteAllText instead :)