防止在 PowerShell Out-File 命令中尾随换行符
Prevent trailing newline in PowerShell Out-File command
如何防止 PowerShell 的 Out-File 命令在其输出的文本后附加换行符?
例如,运行 下面的命令生成一个包含内容 "TestTest\r\n" 而不仅仅是 "TestTest".
的文件
"TestTest" | Out-File -encoding ascii test.txt
在 PowerShell 5.0+ 中,您将使用:
"TestTest" | Out-File -encoding ascii test.txt -NoNewline
但在早期版本中,您根本无法使用该 cmdlet。
试试这个:
[System.IO.File]::WriteAllText($FilePath,"TestTest",[System.Text.Encoding]::ASCII)
补充再-NoNewline
:
以下不仅适用于 Out-File
,也适用于 Set-Content
/ Add-Content
;如前所述,-NoNewline
需要 PSv5+。
注意-NoNewline
表示用多个对象输出,不仅 trailing 换行符(换行符)被抑制,而且 any 换行符。
换句话说:输入对象的字符串表示直接连接,没有分隔符(终止符)。
因此,以下命令产生相同的文件内容(TestTest
没有尾随换行符):
# 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
为了 仅在 之间放置换行符,而不 在 输出对象之后, 您必须 明确地用换行符加入对象:
"Test", "Test" -join [Environment]::NewLine |
Out-File -encoding ascii test.txt -NoNewline
[Environment]::NewLine
是适合平台的换行符序列(在 Windows 上是 CRLF,在类 Unix 平台上是 LF);如果需要,您还可以使用 "`r`n"
和 "`n"
显式生成任一序列
警告:
上述 -join
解决方案隐式地将输入对象转换为字符串(如果它们尚未转换),并且通过对每个对象调用 .NET .ToString()
方法来实现。这通常会产生与 Out-File
直接创建的表示不同的表示,因为 Out-File
使用 PowerShell 的 默认输出格式化程序 ;例如,比较 (Get-Date).ToString()
和 Get-Date
.
的输出
如果您的输入仅包含字符串 and/or 非字符串,其 .ToString()
表示令人满意,上述解决方案有效,但请注意它是通常最好使用 Set-Content
cmdlet,它隐含地应用相同的字符串化。
有关 Out-File
和 Set-Content
之间差异的完整讨论,请参阅我的 this answer。
如果您的输入有非字符串,您希望按照它们打印到控制台的方式进行格式化,实际上没有简单的解决方案:虽然您可以使用 Out-String
创建每个对象的字符串表示使用默认格式化程序,Out-String
缺少 -NoNewline
(从 v5.1 开始;this GitHub issue 建议引入它)总是会产生尾随换行符。
为了补充 briantist 和 mklement0 的有用答案 -NoNewline:
我创建了这个小函数来替换以前版本的 powershell 中 Out-File 的 -NoNewLine 参数。
注意:在我的例子中,它是一个包含 7 行的 .csv 文件(星期几和更多值)
## 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
}
}
如何防止 PowerShell 的 Out-File 命令在其输出的文本后附加换行符?
例如,运行 下面的命令生成一个包含内容 "TestTest\r\n" 而不仅仅是 "TestTest".
的文件"TestTest" | Out-File -encoding ascii test.txt
在 PowerShell 5.0+ 中,您将使用:
"TestTest" | Out-File -encoding ascii test.txt -NoNewline
但在早期版本中,您根本无法使用该 cmdlet。
试试这个:
[System.IO.File]::WriteAllText($FilePath,"TestTest",[System.Text.Encoding]::ASCII)
补充-NoNewline
:
以下不仅适用于 Out-File
,也适用于 Set-Content
/ Add-Content
;如前所述,-NoNewline
需要 PSv5+。
注意-NoNewline
表示用多个对象输出,不仅 trailing 换行符(换行符)被抑制,而且 any 换行符。
换句话说:输入对象的字符串表示直接连接,没有分隔符(终止符)。
因此,以下命令产生相同的文件内容(TestTest
没有尾随换行符):
# 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
为了 仅在 之间放置换行符,而不 在 输出对象之后, 您必须 明确地用换行符加入对象:
"Test", "Test" -join [Environment]::NewLine |
Out-File -encoding ascii test.txt -NoNewline
[Environment]::NewLine
是适合平台的换行符序列(在 Windows 上是 CRLF,在类 Unix 平台上是 LF);如果需要,您还可以使用 "`r`n"
和 "`n"
警告:
上述 -join
解决方案隐式地将输入对象转换为字符串(如果它们尚未转换),并且通过对每个对象调用 .NET .ToString()
方法来实现。这通常会产生与 Out-File
直接创建的表示不同的表示,因为 Out-File
使用 PowerShell 的 默认输出格式化程序 ;例如,比较 (Get-Date).ToString()
和 Get-Date
.
如果您的输入仅包含字符串 and/or 非字符串,其 .ToString()
表示令人满意,上述解决方案有效,但请注意它是通常最好使用 Set-Content
cmdlet,它隐含地应用相同的字符串化。
有关 Out-File
和 Set-Content
之间差异的完整讨论,请参阅我的 this answer。
如果您的输入有非字符串,您希望按照它们打印到控制台的方式进行格式化,实际上没有简单的解决方案:虽然您可以使用 Out-String
创建每个对象的字符串表示使用默认格式化程序,Out-String
缺少 -NoNewline
(从 v5.1 开始;this GitHub issue 建议引入它)总是会产生尾随换行符。
为了补充 briantist 和 mklement0 的有用答案 -NoNewline:
我创建了这个小函数来替换以前版本的 powershell 中 Out-File 的 -NoNewLine 参数。
注意:在我的例子中,它是一个包含 7 行的 .csv 文件(星期几和更多值)
## 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
}
}