【问题标题】:How do I add a newline to command output in PowerShell?如何在 PowerShell 的命令输出中添加换行符?
【发布时间】:2010-12-10 23:46:32
【问题描述】:

我使用 PowerShell 运行以下代码以从注册表中获取添加/删除程序的列表:

Get-ChildItem -path hklm:\software\microsoft\windows\currentversion\uninstall `
    | ForEach-Object -Process { Write-Output $_.GetValue("DisplayName") } `
    | Out-File addrem.txt

我希望每个程序都用换行符分隔列表。我试过了:

Get-ChildItem -path hklm:\software\microsoft\windows\currentversion\uninstall `
    | ForEach-Object -Process { Write-Output $_.GetValue("DisplayName") `n } `
    | out-file test.txt

Get-ChildItem -path hklm:\software\microsoft\windows\currentversion\uninstall `
    | ForEach-Object {$_.GetValue("DisplayName") } `
    | Write-Host -Separator `n

Get-ChildItem -path hklm:\software\microsoft\windows\currentversion\uninstall `
    | ForEach-Object -Process { $_.GetValue("DisplayName") } `
    | foreach($_) { echo $_ `n }

但是当输出到控制台时,所有这些都会导致奇怪的格式,并且当输出到文件时,每行后面都有三个方形字符。我尝试了Format-ListFormat-TableFormat-Wide,但没有成功。最初,我认为这样的事情会起作用:

Get-ChildItem -path hklm:\software\microsoft\windows\currentversion\uninstall `
    | ForEach-Object -Process { "$_.GetValue("DisplayName") `n" }

但这只是给了我一个错误。

【问题讨论】:

  • Get-ChildItem -path hklm:\software\microsoft\windows\currentversion\uninstall ` | ForEach-Object -Process { "$($_.GetValue("DisplayName")) `n" }

标签: powershell newline


【解决方案1】:

或者,只需将output field separator (OFS) 设置为双换行符,然后确保在将其发送到文件时得到一个字符串:

$OFS = "`r`n`r`n"
"$( gci -path hklm:\software\microsoft\windows\currentversion\uninstall | 
    ForEach-Object -Process { write-output $_.GetValue('DisplayName') } )" | 
 out-file addrem.txt

注意使用 ` 而不是 '。在我的键盘(美式英语 Qwerty 布局)上,它位于 1 的左侧。
(从 cmets 移到这里 - 感谢 Koen Zomers)

【讨论】:

  • 这确实有效。但是,如果添加了任何其他值,即 $_.GetValue('InstallDate'),那么它就会搞砸。它解决了最初的问题,所以感谢您的帮助。
  • 我在下面添加了一个替代答案,我认为它可能更好:)
【解决方案2】:

试试这个:

PS> $nl = [Environment]::NewLine
PS> gci hklm:\software\microsoft\windows\currentversion\uninstall | 
        ForEach { $_.GetValue("DisplayName") } | Where {$_} | Sort |
        Foreach {"$_$nl"} | Out-File addrem.txt -Enc ascii

它在我的 addrem.txt 文件中生成以下文本:

Adobe AIR

Adobe Flash Player 10 ActiveX

...

注意:在我的系统上,GetValue("DisplayName") 对某些条目返回 null,因此我将它们过滤掉。顺便说一句,你很接近这个:

ForEach-Object -Process { "$_.GetValue("DisplayName") `n" }

除了在字符串中,如果你需要访问一个变量的属性,即“评估一个表达式”,那么你需要像这样使用子表达式语法:

Foreach-Object -Process { "$($_.GetValue('DisplayName'))`r`n" }

基本上在双引号字符串中,PowerShell 将扩展变量,如$_,但它不会评估表达式除非您使用以下语法将表达式放在子表达式中:

$(`<Multiple statements can go in here`>).

【讨论】:

  • 我尝试了上述两个建议,但格式仍然不是 100%。每个换行符在记事本中显示为一个小方块(可能是 unicode?)。在写字板中一切似乎都很好,但 Word 抱怨编码。使用 Foreach { "$($_.GetValue('DisplayName'))`n" } 仍然在任何文件中输出错误的格式。
  • Powershell 的默认输出是 Unicode。我将修改示例以显示如何以 ascii 格式保存。
  • 我已经尝试了输出文件的所有编码选项,但没有一个给我正确的结果。我检查了环境变量 $OutputEncoding,一切都出现了 US-ASCII。我想我会尝试一种不同的方法,也许是在 python 中。
【解决方案3】:

我认为您对上一个示例的想法是正确的。你只得到了一个错误,因为你试图在一个已经引用过的字符串中加上引号。这将解决它:

gci -path hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object -Process { write-output ($_.GetValue("DisplayName") + "`n") }

编辑:Keith 的 $() 运算符实际上创建了一种更好的语法(我总是忘记这个)。您还可以像这样在引号内转义引号:

gci -path hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object -Process { write-output "$($_.GetValue(`"DisplayName`"))`n" }

【讨论】:

  • 这是问题的正确答案。这应该是公认的答案。
【解决方案4】:

最终,您尝试对每个空行之间的额外空行做些什么有点令人困惑:)

我认为你真正想做的是使用Get-ItemProperty。缺少值时会出现错误,但您可以使用 -ErrorAction 0 隐藏它们或将它们留作提醒。由于 Registry 提供程序返回额外的属性,您需要坚持使用与 Get-Properties 相同的属性的Select-Object

然后,如果您希望每个属性在一行之间有一个空行,请使用Format-List(否则,使用Format-Table 获取每行一个)。

gci -path hklm:\software\microsoft\windows\currentversion\uninstall |
gp -Name DisplayName, InstallDate | 
select DisplayName, InstallDate | 
fl | out-file addrem.txt

【讨论】:

  • 是的!我应该从一开始就这样做,而不是搞乱新行。谢谢您的帮助!真的很感激。
【解决方案5】:

我倾向于使用的选项是使用Write-Output,主要是因为它很简单而且我不必思考,如下所示。 Write-Output 将为您在字符串中放置一个 EOL 标记,您可以简单地输出完成的字符串。

Write-Output $stringThatNeedsEOLMarker | Out-File -FilePath PathToFile -Append

或者,您也可以使用 Write-Output 构建整个字符串,然后将完成的字符串推送到 Out-File

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-26
    • 2016-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多