Dividir comandos largos en varias líneas a través del archivo por lotes de Windows

735

¿Cómo puedo dividir comandos largos en varias líneas en un archivo por lotes?

Ondra Žižka
fuente

Respuestas:

919

Puede romper largas líneas con el cursor ^mientras recuerde que el cursor y la nueva línea que lo sigue se eliminan por completo. Por lo tanto, si debe haber un espacio donde está rompiendo la línea, incluya un espacio. ( Más sobre eso a continuación ) .

Ejemplo:

copy file1.txt file2.txt

se escribiría como:

copy file1.txt^
 file2.txt
Wayne
fuente
95
Puede comenzar la siguiente línea sin un espacio si agrega un espacio justo antes ^y después del texto del comando.
Joseph Daigle
44
@SebaIllingworth: No, siempre puede agregar [ESPACIO] + [^] y dos líneas en blanco para crear un total de 2 saltos de línea cuando se echoedita.
James K
12
Para mayor seguridad, siempre termine con una línea en blanco cuando use los carets, consulte Quilate simple en el archivo por lotes consume toda la memoria
matt wilkie
44
@GavinMiller: "caret ^ después de copiar y file1.txt en una nueva línea no funcionará" Eso no es cierto. Puede dividir la línea en cualquier lugar, incluso en el medio de una palabra, como co^␍py ^␍file1 ^␍file2. Le sugiero que elimine su comentario para evitar confusiones, especialmente porque esta pregunta es tan popular
Borodin
3
Un problema aquí es que el ^ tiene que ser el último carácter de la línea, es decir, sin espacios después. Estaba teniendo problemas con esto y resultó que tenía un montón de espacios después de la interrupción, no fácilmente visible en el editor que estaba usando.
GregHNZ
267

La regla para el caret es:

Un cursor al final de la línea, agrega la siguiente línea, se escapará el primer carácter de la línea adjunta.

Puede usar el cursor varias veces, pero la línea completa no debe exceder la longitud máxima de línea de ~ 8192 caracteres (Windows XP, Windows Vista y Windows 7).

echo Test1
echo one ^
two ^
three ^
four^
*
--- Output ---
Test1
one two three four*

echo Test2
echo one & echo two
--- Output ---
Test2
one
two

echo Test3
echo one & ^
echo two
--- Output ---
Test3
one
two

echo Test4
echo one ^
& echo two
--- Output ---
Test4
one & echo two

Para suprimir el escape del siguiente personaje, puede usar una redirección.

La redirección tiene que ser justo antes del cursor. Pero existe una curiosidad con la redirección antes del caret.

Si coloca una ficha en el cursor, se elimina la ficha.

echo Test5
echo one <nul ^
& echo two
--- Output ---
Test5
one
two


echo Test6
echo one <nul ThisTokenIsLost^
& echo two
--- Output ---
Test6
one
two

Y también es posible insertar avances de línea en la cadena:

setlocal EnableDelayedExpansion
set text=This creates ^

a line feed
echo Test7: %text%
echo Test8: !text!
--- Output ---
Test7: This creates
Test8: This creates
a line feed

La línea vacía es importante para el éxito. Esto funciona solo con expansión retrasada, de lo contrario, el resto de la línea se ignora después del avance de línea.

Funciona porque el cursor al final de la línea ignora el siguiente avance de línea y escapa al siguiente carácter, incluso si el siguiente carácter también es un avance de línea (los retornos de carro siempre se ignoran en esta fase).

jeb
fuente
El bloque de código final con el ejemplo de avance de línea no muestra la línea en blanco, aunque esté allí. (Al menos no aparece en IE7) Intente reformatear usando una cita en bloque.
dbenham
55
La pregunta es, ¿deberíamos admitir una mala herramienta que no siguió las reglas (alguien lo llama navegador, pero no lo es) o debería cambiar a un navegador?
jeb
1
Tenía comillas dobles alrededor de mis valores, como en el conjunto var = "texto aquí ^" pero no funciona. Elimine la comilla doble y está bien.
rjt
1
@jeb, escribió un script de cmd que falla, pero luego encontró esta pregunta: stackoverflow.com/questions/4643376/…
rjt
Esto no funciona si la siguiente línea comienza con comillas: ¡ copy ^[newline]"file1.txt" ^[newline]"file2.txt"no funciona! He tenido que añadir un espacio: copy ^[newline] "file1.txt" ^[newline] "file2.txt".
Alexander Gelbukh
70

(Esto es básicamente una reescritura de la respuesta de Wayne, pero con la confusión alrededor del cursor despejado. Así que lo publiqué como CW. No me da miedo editar las respuestas, pero reescribirlas por completo parece inapropiado).

Puede dividir líneas largas con el símbolo de intercalación ( ^), solo recuerde que el símbolo de intercalación y la nueva línea que sigue se eliminan por completo del comando, por lo que si lo coloca donde se necesitaría un espacio (como entre los parámetros), asegúrese de para incluir también el espacio (ya sea antes ^o al comienzo de la siguiente línea; esa última opción puede ayudar a aclarar que es una continuación).

Ejemplos: (todos probados en Windows XP y Windows 7)

xcopy file1.txt file2.txt

Se puede escribir como:

xcopy^
 file1.txt^
 file2.txt

o

xcopy ^
file1.txt ^
file2.txt

o incluso

xc^
opy ^
file1.txt ^
file2.txt

(Eso último funciona porque no hay espacios entre el xcy el ^, y no hay espacios al comienzo de la siguiente línea. Entonces, cuando eliminas el ^y la nueva línea, obtienes ... xcopy).

Para facilitar la lectura y la cordura, probablemente sea mejor dividir solo entre parámetros (asegúrese de incluir el espacio).

Asegúrese de que no^ sea lo último en un archivo por lotes, ya que parece haber un problema importante con eso .

T.J. Crowder
fuente
18

Se pueden poner múltiples comandos entre paréntesis y distribuirlos en numerosas líneas; así que algo así echo hi && echo hellose puede poner así:

( echo hi
  echo hello )

También las variables pueden ayudar:

set AFILEPATH="C:\SOME\LONG\PATH\TO\A\FILE"
if exist %AFILEPATH% (
  start "" /b %AFILEPATH% -option C:\PATH\TO\SETTING...
) else (
...

También noté con carets ( ^) que a los ifcondicionales les gustaba que siguieran solo si había un espacio presente:

if exist ^
Perdiz de Todd
fuente
1
La línea cmd1.bat && cmd2.bates diferente de la forma parens: ejecutar cmd2.batiff se cmd1.batejecutó con éxito (-sin configuración %errorcode%). La última forma se ejecuta incondicionalmente. Algo inesperado (al menos para mí) es que, obviamente, no puede usar la combinación de ambos +, es decir, agregar &&antes del salto de línea.
Paul Michalik
( echo <line break here> hello )da como resultado una línea vacía.
Karl Morrison
¡La mejor y más limpia respuesta! los carets son feos y problemáticos en regex
neoscribe
9

Sin embargo, parece que dividir en el medio de los valores de un bucle for no necesita un intercalado (e intentar usar uno se considerará un error de sintaxis). Por ejemplo,

for %n in (hello
bye) do echo %n

Tenga en cuenta que ni siquiera se necesita espacio después de hola o antes de adiós.

Mohammed Safwat
fuente
Por supuesto, esto es parte de la forsintaxis: los separadores de elementos en "for-set" son espacio, coma, punto y coma, signo igual, carácter TAB y líneas nuevas.
Aacini
Pero, ¿qué pasa si la doparte contiene if-elsedeclaraciones múltiples / anidadas ?
Vicky Dev
Luego, simplemente puede usar paréntesis para encerrar las declaraciones como por ejemplo% n en (hola adiós) do (echo% n echo% n)
Mohammed Safwat