Set-Content在文件末尾追加了换行符(换行符,CRLF) [英] Set-Content appends a newline (line break, CRLF) at the end of my file
问题描述
我的原始配置文件(web1.config)没有多余的行,并且在记事本中查看(显示所有字符)时看起来像:
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')
因此,生成的新文件(web1.config)如下:
So, the new file (web1.config) generated looks as:
请注意,在文件末尾添加了多余的行(完全不需要) 我尝试了所有其他选项,例如: -使用文件外API -使用.net IO方法System.IO.StreamWriter -使用-nonewline标志(它将所有10行转换为单行) -使用不同的编码选项 -尝试将\ r \ n替换为\ r(不再起作用,因为set-content始终会生成crlf)
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)
我正在使用PowerShell v5.1.
I'm using PowerShell v5.1.
推荐答案
tl; dr ( PSv5 + ;请参见底部的旧版本):
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
注意:如果要Windows样式的CRLF行尾而不是Unix样式的仅LF行尾(PowerShell和许多实用程序都可以处理),请用"`r`n"
替换"`n"
.
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).
在 PSv5 + 中,Set-Content
支持 -NoNewline
开关,该开关指示Set-Content
请勿在每次输入后添加换行符(换行符)对象.类似地,Add-Content
和Out-File
cmdlet也是如此.
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.
换句话说: Set-Content -NoNewline
直接连接 all 其输入对象的字符串表示形式:
In other words: Set-Content -NoNewline
directly concatenates the string representations of all its input objects:
> 'one', 'two' | Set-Content -NoNewline tmp.txt; Get-Content tmp.txt
onetwo
如果要传递给Set-Content -NoNewline
的是已经嵌入换行符的单个字符串,则可以按原样使用它并获得所需的结果:
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:
> "one`ntwo" | Set-Content -NoNewline tmp.txt; "$(Get-Content -Raw tmp.txt)?"
one
two?
请注意,Get-Content -Raw
会按原样读取文件()(除了字符解码),并且?
直接出现在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.
在您的情况下,由于您要逐行处理输入线 (通过Get-Content
而没有 -Raw
),因此输出数组行(字符串),您必须首先用换行符将它们连接为分隔符 -仅在行之间 -并传递结果到Set-Content -NoNewline
,如顶部所示;这是一个简化的示例:
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:
> ('one', 'two') -join "`n" | Set-Content -NoNewline tmp.txt; "$(Get-Content -Raw tmp.txt)?"
one
two?
'one', 'two'
是一个由两个元素组成的字符串数组,可作为您逐行处理命令的替代.
'one', 'two'
is a two-element string array that is a stand-in for your line-by-line processing command.
编码说明:
在Windows PowerShell中,默认情况下,Set-Content
根据系统的旧式单字节代码页生成"ANSI"编码的文件.
要显式控制编码,请使用-Encoding
参数.
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.
在 PSv4-中,需要使用.NET Framework的解决方案:
In PSv4-, a solution that uses the .NET Framework is needed:
> [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]
编码实例作为第三个参数传递.
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.
这篇关于Set-Content在文件末尾追加了换行符(换行符,CRLF)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!