Lote de Windows: eco sin nueva línea

¿Cuál es el equivalente en lotes de Windows del comando de shell de Linux echo -n que suprime la nueva línea al final de la salida?

La idea es escribir en la misma línea dentro de un bucle.

Usando set y el parámetro /p puedes hacer eco sin nueva línea:

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

Fuente

Usando: echo | set /p= echo | set /p= or funcionarán para suprimir la nueva línea.

Sin embargo, esto puede ser muy peligroso cuando se escriben scripts más avanzados cuando la comprobación de ERRORLEVEL se vuelve importante, ya que establecer set /p= sin especificar un nombre de variable establecerá ERRORLEVEL en 1.

Un mejor enfoque sería simplemente usar un nombre de variable ficticia como ese:
echo | set /p dummyName=Hello World

Esto producirá exactamente lo que quieres sin ningún tipo de cosas furtivas sucediendo en el fondo, ya que tuve que descubrir de la manera difícil, pero esto solo funciona con la versión por cable; aún elevará el ERRORLEVEL a 1.

El método simple SET / P tiene limitaciones que varían ligeramente entre las versiones de Windows.

  • Las citas líderes pueden ser despojadas

  • Líder de espacio en blanco puede ser eliminado

  • Leading = causa un error de syntax.

Consulte http://www.dostips.com/forum/viewtopic.php?f=3&t=4209 para obtener más información.

jeb publicó una solución inteligente que resuelve la mayoría de los problemas en Texto de salida sin avance de línea, incluso con espacio inicial o = He refinado el método para que pueda imprimir absolutamente cualquier cadena de lote válida sin la nueva línea, en cualquier versión de Windows desde XP en adelante. Tenga en cuenta que el método :writeInitialize contiene un literal de cadena que puede no publicarse correctamente en el sitio. Se incluye una observación que describe cuál debería ser la secuencia de caracteres.

Los métodos :write y :writeVar están optimizados de tal forma que solo se escriben cadenas que contienen caracteres principales problemáticos usando mi versión modificada del método COPY de jeb. Las cadenas sin problemas se escriben usando el método SET / P más simple y rápido.

 @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 ( "%$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!"  or 0x1A :: :: $write.problemChars - list of characters that cause problems for SET /P ::     <0xFF>   :: Note that  and  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   <0xFF> ) exit /b 

Una solución para el espacio en blanco eliminado en SET / P:

el truco es ese carácter de retroceso que puede invocar en el editor de texto EDITAR para DOS. Para crearlo en EDITAR presione ctrlP + ctrlH . Me gustaría pegar aquí, pero esta página web no puede mostrarlo. Sin embargo, es visible en el Bloc de notas (es werid, como un pequeño rectángulo negro con un círculo blanco en el centro)

Entonces escribes esto:

  

El punto puede ser cualquier char, solo está ahí para decirle a SET / P que el texto comienza allí, antes de los espacios, y no en el " Hola ". El " 9 " es una representación del carácter de retroceso que no puedo mostrar aquí. Tienes que ponerlo en lugar del 9, y eliminará el " . ", Después de lo cual obtendrás esto:

  Hello Everyone 

en lugar de:

 Hello Everyone 

Espero que ayude

Puede eliminar la nueva línea usando “tr” de gnuwin32 (paquete coreutils )

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

Por cierto, si haces muchas secuencias de comandos, gnuwin32 es una mina de oro.

Como una adición a la respuesta de @xmechanix, me di cuenta al escribir los contenidos en un archivo:

 echo | set /p dummyName=Hello World > somefile.txt 

Esto agregará un espacio adicional al final de la cadena impresa , lo que puede ser inconveniente, especialmente porque estamos tratando de evitar agregar una nueva línea (otro carácter de espacio en blanco) al final de la cadena.

Afortunadamente, citando la cadena que se imprimirá, es decir, usando:

 echo | set /p dummyName="Hello World" > somefile.txt 

Imprimirá la cadena sin ningún carácter de nueva línea o espacio al final.

Aquí hay otro método, usa Powershell Write-Host que tiene un parámetro -NoNewLine, combine eso con start /b y ofrece la misma funcionalidad de lote.

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 

Salida

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

Este de abajo es ligeramente diferente, no funciona exactamente como lo quiere OP, pero es interesante porque cada resultado sobrescribe el resultado anterior emulando un contador.

 @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 

Tal vez esto es lo que estás buscando, es un guión de la vieja escuela …: P

 set nl=^& echo. echo %nl%The%nl%new%nl%line%nl%is%nl%not%nl%apparent%nl%throughout%nl%text%nl% echo only in prompt. pause 

o tal vez tratando de reemplazar una línea actual en lugar de escribir en una nueva línea? Puedes experimentar con esto eliminando el “% bs%” después del “.” firmar y también espaciando el otro “% bs%” después del “Mensaje de ejemplo”.

 for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "bs=%%a"  

Encuentro esto realmente interesante porque usa una variable para un propósito diferente de lo que está destinado a hacer. como puede ver, "% bs%" representa un retroceso. El segundo "% bs%" utiliza el retroceso para agregar espacios después del "Mensaje de ejemplo" para separar el "resultado del comando Pausa" sin agregar realmente un carácter visible después del "Mensaje de ejemplo". Sin embargo, esto también es posible con un signo de porcentaje regular.

De aquí

  

y también para hacer eco comenzando con el uso de espacios

 echo.Message goes here 

cw.exe DIY cw.exe (escritura de consola)

Si no lo encuentra listo para usar, puede comprarlo. Con esta utilidad cw puedes usar todo tipo de personajes. Al menos, me gustaría pensar eso. Por favor, prueba de estrés y házmelo saber.

Herramientas

Todo lo que necesita es .NET instalado, que es muy común hoy en día.

Materiales

Algunos caracteres escritos / copiados y pegados.

Pasos

  1. Crea un archivo .bat con el siguiente contenido.
 /* >nul 2>&1 @echo off setlocal set exe=cw for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d /o:-n "%SystemRoot%\Microsoft.NET\Framework\*csc.exe"') do set "csc=%%v" "%csc%" -nologo -out:"%exe%.exe" "%~f0" endlocal exit /b %errorlevel% */ using System; namespace cw { class Program { static void Main() { var exe = Environment.GetCommandLineArgs()[0]; var rawCmd = Environment.CommandLine; var line = rawCmd.Remove(rawCmd.IndexOf(exe),exe.Length).TrimStart('"'); line = line.Length < 2 ? "\r" : line.Substring(2) ; Console.Write(line); } } } 
  1. Ejecutarlo.

  2. Ahora tiene una buena utilidad de 4 KB para que pueda eliminar el .bat .

Alternativamente, puede insertar este código como una subrutina en cualquier lote, enviar el .exe resultante a %temp% , usarlo en su lote y eliminarlo cuando haya terminado.

Cómo utilizar

Si quieres escribir algo sin una nueva línea:
cw Whatever you want, even with "", but remember to escape ^|, ^^, ^&, etc. unless double-quoted, like in "| ^ &".

Si desea un retorno de carro (yendo al comienzo de la línea), ejecute solo
cw

Así que intente esto desde la línea de comando:

 for /l %a in (1,1,1000) do @(cw ^|&cw&cw /&cw&cw -&cw&cw \&cw) 

Puede suprimir la nueva línea usando el comando set / p. El comando set / p no reconoce un espacio, para eso puede usar un punto y un carácter de retroceso para que lo reconozca. También puede usar una variable como memoria y almacenar lo que desea imprimir en ella, para que pueda imprimir la variable en lugar de la oración. Por ejemplo:

 @echo off setlocal enabledelayedexpansion for /f %%a in ('"prompt $H & for %%b in (1) do rem"') do (set "bs=%%a") cls set "var=Hello World! :)" set "x=0" :loop set "display=!var:~%x%,1!" nul set /a "x=%x% + 1" if "!var:~%x%,1!" == "" goto end goto loop :end echo. pause exit 

De esta forma, puede imprimir cualquier cosa sin una nueva línea. He creado el progtwig para imprimir los caracteres uno por uno, pero también puede usar palabras en lugar de caracteres cambiando el ciclo.

En el ejemplo anterior, utilicé “enabledelayedexpansion” para que el comando set / p no reconozca “!” personaje e imprime un punto en lugar de eso. Espero que no tenga el uso del signo de exclamación “!” 😉

Muestra 1: Esto funciona y produce el código de salida = 0. Eso es bueno. Nota la “.” , directamente después del eco.

C: \ Users \ phife.dog \ gitrepos \ 1 \ repo_abc \ scripts #
@echo. | set / p JUNK_VAR = Este es un mensaje que se muestra como el eco de Linux -n lo mostraría … & echo% ERRORLEVEL%

Este es un mensaje que se muestra como el eco de Linux -n lo mostraría … 0

Muestra 2: Esto funciona pero produce el código de salida = 1. Eso es malo. Tenga en cuenta la falta de “.”, Después del eco. Esa parece ser la diferencia.

C: \ Users \ phife.dog \ gitrepos \ 1 \ repo_abc \ scripts #
@echo | set / p JUNK_VAR = Este es un mensaje que se muestra como el eco de Linux -n lo mostraría … & echo% ERRORLEVEL%

Este es un mensaje que se muestra como el eco de Linux -n lo mostraría … 1

Creo que no hay tal opción. Alternativamente puedes intentar esto

 set text=Hello set text=%text% world echo %text% 

Última respuesta aquí, pero para cualquiera que necesite escribir caracteres especiales en una sola línea que encuentre que la respuesta de dbenham es de aproximadamente 80 líneas demasiado largas y cuyos scripts pueden romperse (quizás debido a la entrada del usuario) bajo las limitaciones de simplemente usar un set /p , probablemente sea más fácil emparejar su .bat o .cmd con un ejecutable comstackdo de C ++ o de lenguaje C y luego simplemente cout o printf los caracteres. Esto también le permitirá escribir fácilmente varias veces en una línea si muestra una especie de barra de progreso o algo utilizando caracteres, como aparentemente lo fue OP.

Hice una función a partir de la idea de @arnep:

echo | set / p = “Hola mundo”

aquí está:

 :SL (sameline) echo|set /p=%1 exit /b 

Úselo con call :SL "Hello There"
Sé que esto no es nada especial, pero tardé tanto en pensarlo que pensé que lo publicaría aquí.

puede usar el comando sustituto printf o imprimir y usar retorno de carro en él para lograr esto

ej .: printf “Hello World \ r”

La syntax completa está disponible aquí: http://wiki.bash-hackers.org/commands/builtin/printf