284 votes

Windows batch : echo sans nouvelle ligne

Quel est l'équivalent de la commande batch Windows de la commande shell Linux ? echo -n qui supprime la nouvelle ligne à la fin de la sortie ?

L'idée est d'écrire sur la même ligne à l'intérieur d'une boucle.

3 votes

2 votes

Ça m'a rendu presque fou je savais echo pourrait prendre -n mais sur le cmd.exe ça ne marcherait pas^^

15 votes

@panny - Malgré le nom commun, echo n'est pas la même commande entre Windows et Posix. Tout comme nslookup, elle a des options différentes. Donc le commentaire "Je savais echo pourrait prendre -n "dans le contexte d'une question relative à Windows, est incorrect.

306voto

arnep Points 2737

Utilisation de set et le /p vous pouvez faire l'écho sans nouvelle ligne :

C:\> echo Hello World
Hello World

C:\> echo|set /p="Hello World"
Hello World
C:\>

Source :

107 votes

Le pipe est très lent car il crée deux tâches cmd supplémentaires, le plus rapide est <nul set /p =Hello . set /p ne peut pas faire écho à un signe égal comme premier caractère ni à des espaces/tabulations.

1 votes

@jeb juste par curiosité : avez-vous un benchmark comparant combien ma solution est plus lente ?

16 votes

Il est presque 15 fois plus rapide sur mon système.

135voto

xmechanix Points 260

Utilisation : echo | set /p= o <NUL set /p= fonctionneront toutes deux pour supprimer la nouvelle ligne.

Cependant, cela peut être très dangereux lors de l'écriture de scripts plus avancés, lorsque la vérification de l'ERRORLEVEL devient importante, car le paramétrage set /p= sans spécifier de nom de variable définira le ERRORLEVEL à 1.

Une meilleure approche consisterait à utiliser un nom de variable fictif comme ceci :
echo | set /p dummyName=Hello World

Cela produira exactement ce que vous voulez sans qu'il y ait de trucs sournois en arrière-plan, comme j'ai dû le découvrir à la dure, mais cela ne fonctionne qu'avec la version piped ; <NUL set /p dummyName=Hello fera toujours passer le NIVEAU D'ERREUR à 1.

30 votes

Avertissement : Cette commande mettra ERRORLEVEL à 0. Si ERRORLEVEL était plus grand que 0, il changera ERRORLEVEL à 0. Cela peut également être dangereux lors de l'écriture de scripts plus avancés. (mais +1 pour la réponse)

2 votes

Vous avez donc besoin d'un IF ERRORLEVEL==0 (...) ELSE (...) juste pour ne pas nuire à votre environnement dans ces circonstances. Sheesh.

2 votes

Eh bien, écrire des scripts plus avancés semble déjà assez dangereux en soi :) si ce n'est pour une exécution stable, au moins risqué pour l'état mental de l'auteur.

32voto

dbenham Points 46458

La méthode simple SET /P a des limites qui varient légèrement selon les versions de Windows.

  • Les guillemets peuvent être supprimés

  • Les espaces blancs de tête peuvent être supprimés

  • Chef de file = provoque une erreur de syntaxe.

Voir http://www.dostips.com/forum/viewtopic.php?f=3&t=4209 pour plus d'informations.

jeb a posté une solution intelligente qui résout la plupart des problèmes à Texte de sortie sans saut de ligne, même avec un espace avant ou =. J'ai affiné la méthode de sorte qu'elle puisse imprimer en toute sécurité n'importe quelle chaîne de caractères de lot valide sans la nouvelle ligne, sur n'importe quelle version de Windows à partir de XP. Notez que le :writeInitialize contient une chaîne littérale qui peut ne pas s'afficher correctement sur le site. Une remarque est incluse qui décrit ce que devrait être la séquence de caractères.

El :write y :writeVar sont optimisées de telle sorte que seules les chaînes contenant des caractères de tête gênants sont écrites à l'aide de ma version modifiée de la méthode COPY de Jeb. Les chaînes de caractères qui ne posent pas de problème sont écrites à l'aide de la méthode SET /P, plus simple et plus rapide.

@echo off
setlocal disableDelayedExpansion
call :writeInitialize
call :write "=hello"
call :write " world!%$write.sub%OK!"
echo(
setlocal enableDelayedExpansion
set lf=^

set "str= hello!lf!world^!!!$write.sub!hello!lf!world"
echo(
echo str=!str!
echo(
call :write "str="
call :writeVar str
echo(
exit /b

:write  Str
::
:: Write the literal string Str to stdout without a terminating
:: carriage return or line feed. Enclosing quotes are stripped.
::
:: This routine works by calling :writeVar
::
setlocal disableDelayedExpansion
set "str=%~1"
call :writeVar str
exit /b

:writeVar  StrVar
::
:: Writes the value of variable StrVar to stdout without a terminating
:: carriage return or line feed.
::
:: The routine relies on variables defined by :writeInitialize. If the
:: variables are not yet defined, then it calls :writeInitialize to
:: temporarily define them. Performance can be improved by explicitly
:: calling :writeInitialize once before the first call to :writeVar
::
if not defined %~1 exit /b
setlocal enableDelayedExpansion
if not defined $write.sub call :writeInitialize
set $write.special=1
if "!%~1:~0,1!" equ "^!" set "$write.special="
for /f delims^=^ eol^= %%A in ("!%~1:~0,1!") do (
  if "%%A" neq "=" if "!$write.problemChars:%%A=!" equ "!$write.problemChars!" set "$write.special="
)
if not defined $write.special (
  <nul set /p "=!%~1!"
  exit /b
)
>"%$write.temp%_1.txt" (echo !str!!$write.sub!)
copy "%$write.temp%_1.txt" /a "%$write.temp%_2.txt" /b >nul
type "%$write.temp%_2.txt"
del "%$write.temp%_1.txt" "%$write.temp%_2.txt"
set "str2=!str:*%$write.sub%=%$write.sub%!"
if "!str2!" neq "!str!" <nul set /p "=!str2!"
exit /b

:writeInitialize
::
:: Defines 3 variables needed by the :write and :writeVar routines
::
::   $write.temp - specifies a base path for temporary files
::
::   $write.sub  - contains the SUB character, also known as <CTRL-Z> or 0x1A
::
::   $write.problemChars - list of characters that cause problems for SET /P
::      <carriageReturn> <formFeed> <space> <tab> <0xFF> <equal> <quote>
::      Note that <lineFeed> and <equal> also causes problems, but are handled elsewhere
::
set "$write.temp=%temp%\writeTemp%random%"
copy nul "%$write.temp%.txt" /a >nul
for /f "usebackq" %%A in ("%$write.temp%.txt") do set "$write.sub=%%A"
del "%$write.temp%.txt"
for /f %%A in ('copy /z "%~f0" nul') do for /f %%B in ('cls') do (
  set "$write.problemChars=%%A%%B    ""
  REM the characters after %%B above should be <space> <tab> <0xFF>
)
exit /b

2 votes

C'est agréable de voir une solution très puissante qui peut gérer tous les caractères.

3 votes

Je tiens à souligner que si l'ordinateur dispose d'une connexion réseau à Internet, une telle quantité de code batch peut être utilisée pour télécharger et installer python ou n'importe quoi d'autre sur l'ordinateur, ce qui peut vous débarrasser de batch. Batch est amusant mais ses capacités de chaîne de caractères sont meilleures pour les défis du week-end.

0 votes

@dbenham à la ligne 6 "echo(" c'est fonctionnellement la même chose que "echo". - Je n'ai jamais vu cela auparavant.

8voto

Knuckle-Dragger Points 1828

Voici une autre méthode, elle utilise Powershell Write-Host qui a un paramètre -NoNewLine, combinez cela avec start /b et il offre la même fonctionnalité à partir du lot.

NoNewLines.cmd

@ECHO OFF
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 1 - ';Write-Host -NoNewLine 'Result 2 - ';Write-Host -NoNewLine 'Result 3 - '"
PAUSE

Sortie

Result 1 - Result 2 - Result 3 - Press any key to continue . . .

Celui ci-dessous est légèrement différent, il ne fonctionne pas exactement comme le souhaite l'OP, mais il est intéressant car chaque résultat écrase le résultat précédent en émulant un compteur.

@ECHO OFF
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 1 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 2 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 3 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 4 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 5 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 6 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 7 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 8 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 9 - '"
PAUSE

7voto

Bear Bear Points 395

Vous pouvez supprimer la nouvelle ligne en utilisant "tr" de gnuwin32 ( coreutils paquet)

@echo off
set L=First line
echo %L% | tr -d "\r\n"
echo Second line
pause

Au fait, si vous faites beaucoup de scripts, gnuwin32 est une mine d'or.

0 votes

Je suggère également de installer git bash . bien sûr, ce n'est pas la même chose que gnuwin32 (et c'est une mine d'or donc +1), c'est juste une configuration agréable, et vous avez git-bash sur le bouton droit de la souris presque partout, y compris le bouton du menu de démarrage.

0 votes

Pouvez-vous utiliser tr pour supprimer simplement le dernier caractère d'espacement, comme dans trim ?

0 votes

Utiliser sed pour couper : sed -e "s/ *$//"

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