我的原始配置文件(web1.config)没有额外的行,当在记事本中查看时(显示所有字符)看起来像:
<?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>
现在,我需要应用脚本将我的数据库名称更改为其他类似的内容:
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')
因此,生成的新文件(web1.config)看起来像:
注意文件末尾添加的额外行(完全不需要)我尝试了所有其他选项,例如: - 使用out-file api - 使用.net IO方法System.IO.StreamWriter - 使用-nonewline标志(它将所有10行转换为单行) - 使用不同的编码选项 - 尝试将\ r \ n替换为\ r \ n(不再用作set-content会始终生成crlf)
我正在使用PowerShell v5.1。
tl; dr(PSv5 +;参见旧版本的底部):
(Get-Content webtemp.config) -replace "database=myDb;","database=newDb;" -join "`n" |
Set-Content -NoNewline -Force web1.config
注意:如果您想要Windows样式的CRLF行结尾而不是Unix样式的LF专线结尾(PowerShell和许多实用程序都可以处理两者),请将"`n"
替换为"`r`n"
。
在PSv5 +中,Set-Content
支持-NoNewline
开关,它指示Set-Content
不要在每个输入对象后添加换行符(换行符)。这同样适用于Add-Content
和Out-File
cmdlet。
换句话说:Set-Content -NoNewline
直接连接所有输入对象的字符串表示:
> 'one', 'two' | Set-Content -NoNewline tmp.txt; Get-Content tmp.txt
onetwo
如果您传递给Set-Content -NoNewline
的是一个已经嵌入换行符的单个字符串,您可以按原样使用它并获得所需的结果:
> "one`ntwo" | Set-Content -NoNewline tmp.txt; "$(Get-Content -Raw tmp.txt)?"
one
two?
请注意,Get-Content -Raw
作为一个整体读取文件,除了字符解码之外,以及?
直接出现在two
之后意味着该文件没有尾随换行符的事实。
在你的情况下,由于你正在逐个处理输入行(通过没有Get-Content
的-Raw
)并因此输出一行(字符串),你必须首先用换行符作为分隔符连接它们 - 仅在行之间 - 并通过结果到Set-Content -NoNewline
,如顶部所示;这是一个简化的例子:
> ('one', 'two') -join "`n" | Set-Content -NoNewline tmp.txt; "$(Get-Content -Raw tmp.txt)?"
one
two?
'one', 'two'
是一个双元素字符串数组,是您逐行处理命令的替身。
编码说明:
在Windows PowerShell中,Set-Content
默认根据系统的遗留单字节代码页生成“ANSI”编码文件。
要显式控制编码,请使用-Encoding
参数。
在PSv4-中,需要使用.NET Framework的解决方案:
> [System.IO.File]::WriteAllText('tmp.txt', ('one', 'two') -join "`n"); "$(Get-Content -Raw tmp.txt)?"
one
two?
请注意,在没有编码参数的情况下,[System.IO.File]::WriteAllText()
默认为无BOM的UTF-8。
根据需要将所需的[System.Text.Encoding]
编码实例作为第3个参数传递。
我从来没有注意到这一点,所以我做了一个快速搜索,发现:
set-content adds newlines by default
建议的解决方案是将内容编码为字节,然后使用带有-Encoding参数的Set-Content。
Set-Content test.txt ([byte[]][char[]] "test") -Encoding Byte
我自己测试了,所以我可以确认这是有效的。