如何在PowerShell中的命令输出中添加换行符?


72

我使用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”}
Claudius

Answers:


98

或者,只需将输出字段分隔符(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
(已从评论中移至此处-感谢Koen Zomers)


1
这确实有效。但是,如果添加了任何其他值,即$ _。GetValue('InstallDate'),则它会混乱。它满足了原始问题,但是感谢您的帮助。
麦克

我在下面添加了一个替代答案,我认为可能更好:)
Jaykul

86

试试看:

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中。
迈克,

6

我认为您在上一个示例中有正确的想法。您只收到一个错误,因为您试图将引号放在已经引号的字符串中。这将解决它:

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" }

1
这是对问题的正确答案。这应该是公认的答案。
彼得·莫滕森

6

最终,您试图使用每行之间的EXTRA空白行有点困惑:)

我认为您真正想做的是使用Get-ItemProperty。当值丢失时,您将得到错误,但是您可以将其抑制-ErrorAction 0或保留为提醒。因为注册表提供程序返回了额外的属性,所以您将希望使用与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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.