Comment puis-je afficher du texte sans newline dans PowerShell?

je veux que mon script PowerShell imprime quelque chose comme ceci:

Enabling feature XYZ......Done

le script ressemble à quelque chose comme ceci:

Write-Output "Enabling feature XYZ......."
Enable-SPFeature...
Write-Output "Done"

mais Write-Output imprime toujours une nouvelle ligne à la fin donc ma sortie n'est pas sur une seule ligne. Est-il un moyen de faire cela?

112
demandé sur Peter Mortensen 2010-10-09 19:49:32

14 réponses

Write-Host -NoNewline "Enabling feature XYZ......."
129
répondu Shay Levy 2010-10-09 18:56:13

malheureusement, comme indiqué dans plusieurs réponses et commentaires, Write-Host peut être dangereux et ne peut pas être acheminé à d'autres processus et Write-Output n'a pas le drapeau -NoNewline .

mais ces méthodes sont les" * nix "façons d'afficher la progression, la" PowerShell "façon de faire qui semble être Write-Progress : il affiche une barre au sommet de la fenêtre PowerShell avec des informations sur la progression, disponibles à partir de PowerShell 3.0, voir manuel pour plus de détails.

# Total time to sleep
$start_sleep = 120

# Time to sleep between each notification
$sleep_iteration = 30

Write-Output ( "Sleeping {0} seconds ... " -f ($start_sleep) )
for ($i=1 ; $i -le ([int]$start_sleep/$sleep_iteration) ; $i++) {
    Start-Sleep -Seconds $sleep_iteration
    Write-Progress -CurrentOperation ("Sleep {0}s" -f ($start_sleep)) ( " {0}s ..." -f ($i*$sleep_iteration) )
}
Write-Progress -CurrentOperation ("Sleep {0}s" -f ($start_sleep)) -Completed "Done waiting for X to finish"

et pour prendre l'exemple de L'OP:

# For the file log
Write-Output "Enabling feature XYZ"

# For the operator
Write-Progress -CurrentOperation "EnablingFeatureXYZ" ( "Enabling feature XYZ ... " )

Enable-SPFeature...

# For the operator
Write-Progress -CurrentOperation "EnablingFeatureXYZ" ( "Enabling feature XYZ ... Done" )

# For the log file
Write-Output "Feature XYZ enabled"
24
répondu Thomas 2017-06-04 12:24:13

même si cela ne fonctionne pas dans votre cas (puisque vous fournissez une sortie informative à l'utilisateur), créez une chaîne de caractères que vous pouvez utiliser pour ajouter une sortie. Quand il est temps de le sortir, il suffit de sortir la chaîne.

ignorant bien sûr que cet exemple est stupide dans votre cas mais utile dans le concept:

$output = "Enabling feature XYZ......."
Enable-SPFeature...
$output += "Done"
Write-Output $output

Affiche:

Enabling feature XYZ.......Done
16
répondu shufler 2013-02-14 02:00:29

Oui, comme d'autres réponses l'indiquent, cela ne peut pas être fait en écriture-sortie. Là où PowerShell échoue, tournez-vous vers .NET, il y a même quelques réponses .NET ici, mais elles sont plus complexes qu'elles n'ont besoin d'être.

il suffit d'utiliser:

[Console]::Write("Enabling feature XYZ.......")
Enable-SPFeature...
Write-Output "Done"

ce n'est pas la plus pure PowerShell, mais ça marche.

3
répondu Mark Travis 2017-06-04 12:30:16

Pour écrire dans un fichier, vous pouvez utiliser un tableau d'octets. L'exemple suivant crée un fichier ZIP vide, auquel vous pouvez ajouter des fichiers:

[Byte[]] $zipHeader = 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
[System.IO.File]::WriteAllBytes("C:\My.zip", $zipHeader)

ou utilisation:

[Byte[]] $text = [System.Text.Encoding]::UTF8.getBytes("Enabling feature XYZ.......")
[System.IO.File]::WriteAllBytes("C:\My.zip", $text)
2
répondu FrinkTheBrave 2017-06-04 12:18:39

le problème que j'ai rencontré était que L'écriture-sortie linebreaks réellement la sortie en utilisant PowerShell v2, au moins à stdout. J'ai essayé d'écrire un texte XML à stdout sans succès, parce qu'il serait enveloppé à caractère 80.

la solution était d'utiliser

[Console]::Out.Write($myVeryLongXMLTextBlobLine)

ce n'était pas un problème dans PowerShell v3. L'écriture de Sortie semble fonctionner correctement.

dépend de la façon dont la PowerShell script est invoqué, vous pouvez avoir besoin d'utiliser

[Console]::BufferWidth =< length of string, e.g. 10000)

avant d'écrire à stdout.

2
répondu eythort 2017-06-04 12:21:12

la réponse de shufler est correcte. A déclaré une autre façon: au lieu de passer les valeurs à écrire-sortie en utilisant la forme de tableau,

Write-Output "Parameters are:" $Year $Month $Day

ou l'équivalent par appels multiples à L'écriture-sortie,

Write-Output "Parameters are:"
Write-Output $Year
Write-Output $Month
Write-Output $Day
Write-Output "Done."

concaténez vos composants en une variable STRING first:

$msg="Parameters are: $Year $Month $Day"
Write-Output $msg

cela empêchera les CRLFs intermédiaires causés par l'appel en écriture-sortie plusieurs fois (ou la forme du tableau), mais bien sûr sera ne pas supprimer le CRLF final de la commande Write-Output. Pour cela, vous devrez écrire votre propre commandlet, utiliser l'une des autres solutions de rechange alambiquées énumérées ici, ou attendre que Microsoft décide de prendre en charge l'option -NoNewline pour L'écriture-sortie.

votre désir de fournir un compteur de progression textuel à la console (i.e."....") plutôt que d'écrire dans un fichier journal, devrait également être satisfaits en utilisant Write-Host. Vous pouvez accomplir les deux en recueillant le texte msg dans une variable pour écrire au journal et utiliser Write-Host pour fournir la progression à la console. Cette fonctionnalité peut être combinée dans votre propre commandlet pour une meilleure réutilisation du code.

2
répondu David Rudd 2017-06-04 12:22:49

il semble qu'il n'y ait aucun moyen de faire cela à PowerShell. Toutes les réponses précédentes ne sont pas correctes, parce qu'elles ne se comportent pas de la façon Write-Output se comporte mais plutôt comme Write-Host qui n'a pas ce problème de toute façon.

la solution de fermeture semble utiliser Write-Host avec le paramètre -NoNewLine . Vous ne pouvez pas pipe ce qui est un problème en général, mais il y a un moyen de passer outre à cette fonction comme décrit dans Write-Host => Exporter vers un fichier , de sorte que vous pouvez facilement faire accepter le paramètre pour un fichier de sortie. C'est encore loin d'être une bonne solution. Avec Start-Transcript c'est plus utilisable, mais ce cmdlet a des problèmes avec les applications natives.

Write-Output ne peut tout simplement pas faire ce dont vous avez besoin dans un contexte général.

2
répondu majkinetor 2017-06-04 12:28:38

vous ne pouvez tout simplement pas obtenir PowerShell pour omettre ces nouvelles pesantes... Il n'y a pas de script ou cmdlet qui le fait. Bien sûr, Write-Host est un non-sens absolu, parce que vous ne pouvez pas rediriger / pipe de lui!

Néanmoins, vous pouvez écrire votre propre fichier EXE pour le faire ce qui est ce que j'ai expliqué comment faire dans Stack Overflow question comment produire quelque chose en PowerShell .

1
répondu samthebest 2017-06-04 12:11:19

Write-Host est terrible, un destructeur de mondes, pourtant vous pouvez l'utiliser juste pour afficher le progrès à un utilisateur tout en utilisant Write-out pour se connecter (pas que L'OP a demandé la journalisation).

Write-Output "Enabling feature XYZ" | Out-File "log.txt" # Pipe to log file Write-Host -NoNewLine "Enabling feature XYZ......." $result = Enable-SPFeature $result | Out-File "log.txt" # You could try{}catch{} an exception on Enable-SPFeature depending on what it's doing if ($result -ne $null) { Write-Host "complete" } else { Write-Host "failed" }

1
répondu ATtheincredibleaf 2018-01-05 13:45:52

une simplification de la réponse de FrinkTheBrave:

[System.IO.File]::WriteAllText("c:\temp\myFile.txt", $myContent)
0
répondu Russell Speight 2014-12-25 12:52:40

ce qui suit placera le curseur en arrière au début de la ligne précédente. C'est à vous de le placer dans la bonne position horizontale (en utilisant $pos.X pour le déplacer de côté):

$pos = $host.ui.RawUI.get_cursorPosition()
$pos.Y -= 1
$host.UI.RawUI.set_cursorPosition($Pos)

votre sortie actuelle est de 27 espaces, donc $pos.X = 27 pourrait fonctionner.

0
répondu Will Martin 2015-07-14 17:36:02

ce n'est peut-être pas très élégant, mais il fait exactement ce que L'OP a demandé. Notez que les problèmes avec StdOut, donc il n'y aura pas de sortie. Pour que ce script fonctionne, il ne peut pas être exécuté à l'intérieur de L'ISE.

$stdout=[System.Console]::OpenStandardOutput()
$strOutput="Enabling feature XYZ... "
$stdout.Write(([System.Text.Encoding]::ASCII.GetBytes($strOutput)),0,$strOutput.Length)
Enable-SPFeature...
$strOutput="Done"
$stdout.Write(([System.Text.Encoding]::ASCII.GetBytes($strOutput)),0,$strOutput.Length)
$stdout.Close()
0
répondu Slogmeister Extraordinaire 2017-06-07 16:45:14

vous pouvez absolument le faire. Write-Output a un drapeau appelé " NoEnumerate " qui est essentiellement la même chose.

-2
répondu Smelltastic 2016-10-13 13:55:43