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?
14 réponses
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"
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
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.
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)
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.
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.
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.
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 .
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"
}
une simplification de la réponse de FrinkTheBrave:
[System.IO.File]::WriteAllText("c:\temp\myFile.txt", $myContent)
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.
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()
vous pouvez absolument le faire. Write-Output a un drapeau appelé " NoEnumerate " qui est essentiellement la même chose.