如何防止 PowerShell 脚本中出现尾随换行符?

Ed *_*nac 6 powershell powershell-7.0

即使使用“-NoNewline”,此代码也会添加行

$LST1="OsName","OsVersion","TimeZone","CsName"
$LST2="CsManufacturer","CsModel","CsSystemType","BiosBIOSVersion","BiosReleaseDate"
$MEM1 = (Get-CimInstance Win32_PhysicalMemory | Measure-Object -Property capacity -Sum | Foreach {"{0:N2}" -f ([math]::round(($_.Sum / 1GB),2))})
$Pro1 = "systemname","DeviceID","numberOfCores","NumberOfLogicalProcessors"

Add-Content OutText.txt "OS Information:" -NoNewline
Get-ComputerInfo -Property $LST1 | Format-List | Out-File -Encoding ASCII -FilePath OutText.txt -Append
Add-Content OutText.txt "Hardware Information:" -NoNewline
Get-ComputerInfo -Property $LST2 | Format-List | Out-File -Encoding ASCII -FilePath OutText.txt -Append
Add-Content OutText.txt "RAM: $RAM1 GB" -NoNewline
Get-WmiObject -class win32_processor -Property  $Pro1 | Select-Object -Property $Pro1 | Out-File -FilePath OutText.txt -Encoding ASCII -Append
Run Code Online (Sandbox Code Playgroud)

换行过多:

换行过多

mkl*_*nt0 5

Theo在评论中提供了关键点:

(Get-ComputerInfo -Property $LST1 | Format-List | Out-String).Trim() | 
  Add-Content -Path $path -NoNewline
Run Code Online (Sandbox Code Playgroud)

让我详细说明一下:

  • 为了防止 的输出中的前导和尾随空行通过/Format-List显示在文件中,请首先使用 创建格式化输出的内存中字符串表示形式,Out-File>Out-String

  • 然后,您可以将其应用于.Trim()生成的多行字符串,以便从的输出中删除前导行和尾随行(通常是空格)Out-String

由于Out-String它本身呈现由 输出的格式化指令Format-List,因此您可以使用Set-ContentAdd-Content将结果字符串保存/附加到文件中。


的行为Out-String

Out-String生成与默认情况下在控制台中或通过其他cmdlet(尤其是 /)获得的相同的显示表示形式,默认情况下将其作为单个字符串Out-*Out-File>

虽然这种表示本身可能包含空行,但正如典型情况一样,它Out-String 还会附加一个尾随换行符,尽管没有充分的理由这样做,如GitHub 问题 #14444中所述。

如果您只想删除这个无关的尾随换行符,可以通过-replace运算符使用以下方法(该操作适用于 Windows 风格的 CRLF 换行符 ( \r\n) 和 Unix 风格的仅 LF 换行符 ( \n) ):

(... | Out-String) -replace '\r?\n\z'
Run Code Online (Sandbox Code Playgroud)

或者,效率较低的是,使用开关单独-Stream输出行,然后使用不带尾随的换行符重新连接它们(创建仅 LF 换行符,PowerShell 可以与 CRLF 换行符互换接受该换行符 ( ):"`n""`r`n"

(... | Out-String -Stream) -join "`n"
Run Code Online (Sandbox Code Playgroud)

Out-String应用于外部程序的输出:

Out-String还可以用于捕获外部程序输出的行作为单个多行字符串(默认情况下,PowerShell 逐行捕获输出,在变量中捕获时会生成字符串数组)。

然而,这种使用Out-String有问题的

  • 附加的尾随换行符也可能很麻烦。

  • Windows PowerShell中还有一个额外的麻烦(此问题已在PowerShell (Core) 7+中得到纠正):如果您使用 a2>&1将 stderr 输出合并到成功输出流中,则第一个 stderr 行的格式类似于PowerShell error

    • 运行cmd /c 'echo yes & echo no >&2' 2>&1 | Out-String看看问题。

以下习惯用法避免了这两个问题...代表您的外部程序调用):

$multiLineString = [string[]] (... 2>&1) -join "`n"
Run Code Online (Sandbox Code Playgroud)

注意:上面使用仅 LF 换行符来连接数组元素,这通常就足够了。用于"`r`n"CRLF 换行符或适用[Environment]::NewLine操作系统的换行符序列。

例子

以下cmd.exeCLI 调用输出 stdout 行和 stderr 行,并2>&1在 PowerShell 端将两者合并到成功输出流中。

PS> [string[]] (cmd /c 'echo yes & echo no >&2' 2>&1) -join "`n" |
      ForEach-Object { "[$_]" } # just to visualize the string boundaries 
[yes 
no ]
Run Code Online (Sandbox Code Playgroud)

注意:后面的尾随空格是由于的内置命令no的异常行为造成的:它在输出中包含重定向之前的空格。cmd.exeecho>&2


Ret*_*eek 0

我使用以下内容来去除 Out-String 添加的 Cr/Lf。

$YourVariableHere = $($YourVariableHere.Substring(0,($YourVariableHere.Length-2)))
Run Code Online (Sandbox Code Playgroud)

如果要删除多个 Cr/Lf,您可以调整最后的数字。

华泰