75 votes

Comment ajouter une nouvelle ligne à la sortie de la commande dans PowerShell ?

J'exécute le code suivant à l'aide de powershell pour obtenir une liste de programmes d'ajout/suppression à partir du registre :

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

Je veux que la liste soit séparée par des nouvelles lignes pour chaque programme. J'ai essayé :

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 }

Mais toutes donnent lieu à un formatage bizarre lors de la sortie sur la console, et avec trois caractères carrés après chaque ligne lors de la sortie sur le fichier. J'ai essayé Format-List , Format-Table et Format-Wide sans succès. A l'origine, je pensais que quelque chose comme ça fonctionnerait :

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

Mais ça m'a juste donné une erreur.

0 votes

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

100voto

Jaykul Points 6484

Ou bien, définissez simplement le séparateur de champ de sortie comme étant une double ligne de saut, et assurez-vous d'obtenir une chaîne de caractères lorsque vous l'envoyez au fichier :

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

1 votes

En fait, ça a marché. Mais si d'autres valeurs sont ajoutées, par exemple $_.GetValue('InstallDate'), le problème se pose. Mais cela répond à la question initiale, alors merci pour votre aide.

0 votes

J'ai ajouté une autre réponse ci-dessous qui, à mon avis, est probablement meilleure :)

93voto

Keith Hill Points 73162

Essayez ceci :

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

On obtient le texte suivant dans mon fichier addrem.txt :

Adobe AIR

Adobe Flash Player 10 ActiveX

...

Remarque : sur mon système, GetValue("DisplayName") renvoie un résultat nul pour certaines entrées, que je filtre donc. BTW vous étiez proche avec ceci :

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

Sauf qu'à l'intérieur d'une chaîne de caractères, si vous devez accéder à une propriété d'une variable, c'est-à-dire "évaluer une expression", vous devez utiliser la syntaxe des sous-expressions comme suit :

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

Essentiellement, à l'intérieur d'une chaîne entre guillemets, PowerShell développera les variables comme $_ mais n'évaluera pas les expressions. sauf si vous placez l'expression dans une sous-expression en utilisant cette syntaxe $( <multiple statements can go in here >).

0 votes

J'ai essayé les deux suggestions ci-dessus et le formatage n'est toujours pas à 100%. Chaque nouvelle ligne apparaît comme un petit carré (unicode peut-être ?) dans le Bloc-notes. Dans Wordpad, tout semble correct, mais Word se plaint du codage. L'utilisation de Foreach { "$($_.GetValue('DisplayName'))`n" } produit toujours le mauvais format dans n'importe quel fichier.

0 votes

La sortie par défaut de Powershell est Unicode. Je vais modifier l'exemple pour montrer comment enregistrer au format ascii.

1 votes

J'ai essayé toutes les options d'encodage pour le fichier de sortie et aucune d'entre elles ne m'a donné les bons résultats. J'ai vérifié la variable d'environnement $OutputEncoding et tout est revenu à US-ASCII. Je pense que je vais essayer une approche différente, peut-être en python.

7voto

Ludovic Points 815

Je pense que vous avez eu la bonne idée avec votre dernier exemple. Vous avez seulement eu une erreur parce que vous avez essayé de mettre des guillemets à l'intérieur d'une chaîne déjà citée. Ceci va régler le problème :

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

Edit : L'opérateur $() de Keith crée en fait une meilleure syntaxe (j'oublie toujours celui-ci). Vous pouvez aussi échapper les guillemets à l'intérieur des guillemets comme ceci :

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

1 votes

C'est la réponse correcte à la question. Ceci devrait être la réponse acceptée.

6voto

Jaykul Points 6484

En fin de compte, ce que vous essayez de faire avec les lignes vierges EXTRA entre chaque ligne est un peu confus :)

Je pense que ce que vous voulez vraiment faire, c'est utiliser get-itemproperty. Vous obtiendrez des erreurs lorsque les valeurs sont manquantes, mais vous pouvez les supprimer avec -ErrorAction 0 ou laissez-les simplement comme des rappels. Étant donné que le fournisseur de registre renvoie des propriétés supplémentaires, vous voudrez insérer un Select-Object qui utilise les mêmes propriétés que le Get-Properties.

Ensuite, si vous souhaitez que chaque propriété figure sur une ligne avec une ligne vierge entre les deux, utilisez Format-List (sinon, utilisez Format-Table pour obtenir une propriété par ligne).

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

0 votes

Oui, j'aurais dû faire comme ça dès le début, au lieu de m'embêter avec de nouvelles lignes. Merci pour votre aide ! J'apprécie vraiment.

5voto

InfoSponge Points 11

L'option que j'ai tendance à utiliser, surtout parce que c'est simple et que je n'ai pas à réfléchir, est d'utiliser Write-Output comme ci-dessous. Write-Output mettra un marqueur EOL dans la chaîne pour vous et vous pourrez simplement sortir la chaîne terminée.

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

Alternativement, vous pouvez aussi construire la chaîne entière en utilisant Write-Output et ensuite pousser la chaîne terminée dans Out-File.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X