Lote de Windows: ¿llamar a más de un comando en un bucle FOR?

124

¿Es posible en el archivo por lotes de Windows llamar a más de un comando en un solo FOR bucle? Digamos, por ejemplo, que quiero imprimir el nombre del archivo y después de eliminarlo:

@ECHO OFF
FOR /r %%X IN (*.txt) DO (ECHO %%X DEL %%X)
REM the line above is invalid syntax.

Sé que en este caso podría resolverlo haciendo dos bucles FOR distintos: uno para mostrar el nombre y otro para eliminar el archivo, pero ¿es posible hacerlo solo en un bucle?

Marco Demaio
fuente

Respuestas:

117
FOR /r %%X IN (*) DO (ECHO %%X & DEL %%X)
Piel plateada
fuente
2
En realidad, creo que los paréntesis son innecesarios. for %i in (1 2 3) do echo %i & echo fooimprime lo que esperaría: "1", "foo", "2", "foo", "3", "foo" (en líneas separadas).
bk1e
¿No debería ser eso en &&lugar de &?
jww
9
@jww &&fallará si falla el primer comando, &ejecutará el segundo comando independientemente.
yyny
Si esta solución te produce un error de sintaxis, comprueba si tienes un par sin escapes entre los DOpares. Puede escapar de ellos agregando un ^a ellos.
Константин Ван
199

El uso &está bien para comandos cortos, pero esa sola línea puede ser muy larga y muy rápida. Cuando eso suceda, cambie a la sintaxis de varias líneas.

FOR /r %%X IN (*.txt) DO (
    ECHO %%X
    DEL %%X
)

Colocación (y )materias. Los corchetes posteriores DOdeben colocarse en la misma línea; de lo contrario, el archivo por lotes será incorrecto.

Ver if /?|find /V ""para más detalles.

Anders
fuente
12
Esta solución se ve limpia y legible. También advertiría a cualquier programador que use esta solución que el corchete después de la DONO debe colocarse en la siguiente línea, de lo contrario, frena el archivo por lotes. En el código cuando escribo un bucle for, generalmente coloco el corchete en la {siguiente línea.
Marco Demaio
2
Además, tenga cuidado si alguno de sus comandos anidados tiene corchetes (por ejemplo, algo como "echo Algo algo (otra cosa)" EDITAR: ah, vea la respuesta de bk1e :)
Tim Barrass
31

SilverSkin y Anders son correctos. Puede usar paréntesis para ejecutar múltiples comandos. Sin embargo, debe asegurarse de que los comandos en sí (y sus parámetros) no contengan paréntesis. cmdbusca con avidez el primer paréntesis de cierre, en lugar de manejar conjuntos anidados de paréntesis con gracia. Esto puede hacer que el resto de la línea de comandos no se pueda analizar, o puede hacer que algunos paréntesis pasen a los comandos (por ejemplo DEL myfile.txt)).

Una solución alternativa para esto es dividir el cuerpo del bucle en una función separada. Tenga en cuenta que probablemente necesite saltar alrededor del cuerpo de la función para evitar "caer" en él.

FOR /r %%X IN (*.txt) DO CALL :loopbody %%X
REM Don't "fall through" to :loopbody.
GOTO :EOF

:loopbody
ECHO %1
DEL %1
GOTO :EOF
bk1e
fuente
3
Mientras estamos en el tema,% X nunca es correcto cuando se trata de nombres de archivos, siempre use "% ~ X" (en su ejemplo aquí, podría salirse con el uso de% * en la subfunción probablemente)
Anders
1
Ese es un muy buen punto. Un buen ejemplo de un camino que demuestra ambos problemas es C:\Program Files (x86).
bk1e