My original config file (web1.config) has no extra line and when viewed in notepad (showing all characters) looks as:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.6" />
<httpRuntime targetFramework="4.6" />
</system.web>
<appSettings>
<add key="myConnectionString" value="server=localhost;database=myDb;uid=myUser;password=myPass;" />
</appSettings>
</configuration>
Now, I need to apply the script to change my database name to something else which looks like:
Move-Item "web1.config" "webtemp.config"
Get-Content "webtemp.config" | ForEach-Object {$_ -replace "database=myDb;", "database=newDb;"} |Set-Content "web1.config" -Force
Remove-Item "webtemp.config"
Write-Output('Settings Changed')
So, the new file (web1.config) generated looks as:
Notice the extra line added at the end of the file (which is completely not needed) I tried all other options such as: - using out-file api - using .net IO method System.IO.StreamWriter - using -nonewline flag (it converts all 10 lines into single line) - using different encoding options - tried replacing \r\n to \r (don't work as again set-content generates the crlf always)
I'm using PowerShell v5.1.
Set-Content uses the Path and Value parameters to create a new file named DateTime. txt in the current directory.
To create a new text file and write to it, use the > redirection operator. If you use this operator to write PowerShell stream to a text file, it overwrites the content of the text file. However, if you wan to update a text file without overwriting its content, you use the >> redirection operator.
To edit a file. txt in PowerShell, use the command notepad file. txt to open a graphical editor on Windows. If you need a simple file edit in your terminal without a graphical editor and without installation, you can use the command echo 'new content' > file.
tl;dr (PSv5+; see bottom for older versions):
(Get-Content webtemp.config) -replace 'database=myDb;', 'database=newDb;' -join "`n" |
Set-Content -NoNewline -Force web1.config
Note: Replace "`n"
with "`r`n"
if you want Windows-style CRLF line endings rather than Unix-style LF-only line endings (PowerShell and many utilities can handle both).
In PSv5+, Set-Content
supports the -NoNewline
switch, which instructs Set-Content
not to add a newline (line break) after each input object. The same applies analogously to the Add-Content
and Out-File
cmdlets.
In other words: Set-Content -NoNewline
directly concatenates the string representations of all its input objects:
PS> 'one', 'two' | Set-Content -NoNewline tmp.txt; Get-Content tmp.txt
onetwo
If what you're passing to Set-Content -NoNewline
is a single string that already has embedded newlines, you can use it as-is and get the desired result:
PS> "one`ntwo" | Set-Content -NoNewline tmp.txt; "$(Get-Content -Raw tmp.txt)?"
one
two?
Note that Get-Content -Raw
reads the file as a whole, as-is (aside from character decoding) and the fact that the ?
appears directly after two
implies that the file has no trailing newline.
In your case, since you're processing input lines one by one (via Get-Content
without -Raw
) and therefore outputting an array of lines (strings), you must first join them with a newline as the separator - between lines only - and pass the result to Set-Content -NoNewline
, as shown at the top; here's a simplified example:
PS> ('one', 'two') -join "`n" | Set-Content -NoNewline tmp.txt; "$(Get-Content -Raw tmp.txt)?"
one
two?
'one', 'two'
is a two-element string array that is a stand-in for your line-by-line processing command.
Encoding note:
In Windows PowerShell, Set-Content
produces "ANSI"-encoded files by default, based on your system's legacy, single-byte code page.
To control the encoding explicitly, use the -Encoding
parameter.
In PSv4-, a solution that uses the .NET Framework is needed:
PS> [System.IO.File]::WriteAllText('tmp.txt', ('one', 'two') -join "`n"); "$(Get-Content -Raw tmp.txt)?"
one
two?
Note that [System.IO.File]::WriteAllText()
, in the absence of an encoding argument, defaults to BOM-less UTF-8.
Pass the desired [System.Text.Encoding]
encoding instance as the 3rd argument as needed.
I never noticed this, so i did a quick search and found:
set-content adds newlines by default
The suggested solution is to encode your content to bytes and then use Set-Content with the -Encoding parameter.
Set-Content test.txt ([byte[]][char[]] "test") -Encoding Byte
I tested it myself so i can confirm that this works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With