tag - Lote de Windows: eco sin nueva línea
tag folders (13)
¿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.
Ú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 compilado 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.
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
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.
Creo que no hay tal opción. Alternativamente puedes intentar esto
set text=Hello
set text=%text% world
echo %text%
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 sintaxis.
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 (
<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
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
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.
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 /p "print=.%bs%%display%"
ping -n 1 localhost >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 programa 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 "!" ;)
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"
<nul set /p=.%bs% Example message %bs%
pause
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.
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:/>
Usando: echo | set /p=
echo | set /p=
or <NUL set /p=
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; <NUL set /p dummyName=Hello
aún elevará el ERRORLEVEL a 1.
puede usar el comando sustituto printf o imprimir y usar retorno de carro en él para lograr esto
ej .: printf "Hello World / r"
La sintaxis completa está disponible aquí: http://wiki.bash-hackers.org/commands/builtin/printf
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:
<nul set /p=.9 Hello everyone
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