82 Stimmen

Wie füge ich einen Zeilenumbruch zur Befehlsausgabe in PowerShell hinzu?

Ich führe den folgenden Code mit PowerShell aus, um eine Liste der hinzugefügten/entfernten Programme aus der Registrierung abzurufen:

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

Ich möchte, dass die Liste für jedes Programm durch Zeilenumbrüche getrennt wird. Ich habe es versucht:

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 }

Aber alle führen zu einer seltsamen Formatierung bei der Ausgabe auf der Konsole und zu drei quadratischen Zeichen nach jeder Zeile bei der Ausgabe in eine Datei. Ich habe versucht Format-List , Format-Table y Format-Wide aber ohne Erfolg. Ursprünglich dachte ich, dass etwas wie dies funktionieren würde:

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

Aber das hat mir nur einen Fehler angezeigt.

105voto

Jaykul Punkte 14703

Oder setzen Sie einfach die Ausgangsfeldtrennzeichen (OFS) zu doppelten Zeilenumbrüchen und stellen Sie dann sicher, dass Sie eine Zeichenkette erhalten, wenn Sie sie an die Datei senden:

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

Achten Sie darauf, dass Sie die ` und nicht die ' . Auf meiner Tastatur (US-Englisches Qwerty-Layout) befindet sich die Taste links neben dem 1 .
(Aus den Kommentaren hierher verschoben - Danke Koen Zomers)

100voto

Keith Hill Punkte 183005

Versuchen Sie dies:

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

Das Ergebnis ist der folgende Text in meiner Datei addrem.txt:

Adobe AIR

Adobe Flash Player 10 ActiveX

...

Hinweis: Auf meinem System gibt GetValue("DisplayName") für einige Einträge null zurück, daher filtere ich diese heraus. BTW, Sie waren nah dran mit dem hier:

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

Wenn Sie jedoch innerhalb einer Zeichenkette auf eine Eigenschaft einer Variablen zugreifen, d. h. einen Ausdruck auswerten möchten, müssen Sie die Syntax für Unterausdrücke verwenden:

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

Innerhalb einer Zeichenkette mit doppelten Anführungszeichen erweitert PowerShell im Wesentlichen Variablen wie $_ aber er wertet keine Ausdrücke aus es sei denn, setzen Sie den Ausdruck mit dieser Syntax in einen Unterausdruck:

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

7voto

Ludovic Chabant Punkte 1503

Ich denke, Sie hatten mit Ihrem letzten Beispiel die richtige Idee. Sie haben nur einen Fehler bekommen, weil Sie versucht haben, Anführungszeichen in eine bereits in Anführungszeichen stehende Zeichenkette zu setzen. Dies wird es beheben:

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

Edit: Der $()-Operator von Keith schafft tatsächlich eine bessere Syntax (ich vergesse das immer). Sie können auch Anführungszeichen innerhalb von Anführungszeichen wie so entkommen:

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

7voto

Jaykul Punkte 14703

Letztendlich ist es etwas verwirrend, was Sie mit den EXTRA-Leerzeilen zwischen den einzelnen Zeilen bezwecken :)

Ich denke, was Sie wirklich tun sollten, ist die Verwendung von Get-ItemProperty . Sie erhalten Fehler, wenn Werte fehlen, aber Sie können sie unterdrücken mit -ErrorAction 0 oder lassen Sie sie einfach als Erinnerung stehen. Da der Registry-Anbieter zusätzliche Eigenschaften zurückgibt, sollten Sie eine Objekt auswählen die die gleichen Eigenschaften wie die Get-Properties verwendet.

Wenn Sie dann jede Eigenschaft in einer Zeile mit einer Leerzeile dazwischen haben wollen, verwenden Sie Format-Liste (andernfalls, verwenden Sie Format-Tabelle um eine pro Zeile zu erhalten).

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

6voto

InfoSponge Punkte 104

Die Option, die ich am häufigsten verwende, weil sie einfach ist und ich nicht nachdenken muss, ist die Verwendung von Schreib-Ausgang wie unten. Write-Output setzt für Sie eine EOL-Markierung in den String und Sie können den fertigen String einfach ausgeben.

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

Alternativ könnten Sie auch einfach die gesamte Zeichenkette mit Write-Output erstellen und dann die fertige Zeichenkette in Out-File .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X