batch file - through - ¿En qué punto enumera `for` o` for/R` el directorio(árbol)?
for l cmd (1)
Esta es una excelente pregunta!
Concentrémonos en claro
for
comando por un momento.
Hay un error conocido relacionado con este comando cuando se usa para
cambiar el nombre de los archivos
.
Por ejemplo:
set i=0
for %%a in (*.txt) do (
set /A i+=1
ren "%%a" !i!.txt
)
En este caso, es frecuente que ciertos archivos cambien de nombre dos veces, e incluso tres veces en ciertos casos.
El problema es que este comportamiento depende de una serie de factores que no están documentados, como la posición del primer archivo renombrado dentro de la lista de archivos originales y varios otros puntos.
De manera similar, si un archivo se elimina antes de que sea procesado por
for
,
generalmente se
emite un mensaje "Archivo no encontrado" (aunque no TODAS las veces).
Si se crea un nuevo archivo en el directorio
después
del inicio de la ejecución, entonces puede o no ser procesado por el
for
depender (nuevamente) de una serie de factores.
La forma habitual de evitar el problema con el cambio de nombre es forzar
for
comando a leer primero la lista completa de archivos y
luego
procesar la lista:
for /F "delims=" %%a in (''dir /B *.txt'') do (
set /A i+=1
ren "%%a" !i!.txt
)
De esta manera, no importa los cambios que se pueden hacer en los archivos en el disco: el comando
for /F
siempre procesará la lista de archivos
original
.
Un problema similar ocurre con el comando
for /R
, pero en este caso la posibilidad de problemas es mayor porque hay más directorios donde se pueden realizar cambios dinámicos.
Nuevamente: el comportamiento exacto depende de una serie de factores desconocidos y la forma de evitarlos es mediante
for /F ... in (''dir /S /B'')
.
Sin embargo, si está
realmente
interesado en este punto, le animo a que realice una serie de pruebas sobre el tema (y publique los resultados).
;)
El comando
for
se puede usar para enumerar un directorio y aplicar (a) ciertos comandos en cada elemento.
Con
/R
se puede lograr lo mismo para un árbol de directorios completo.
¿Qué sucede cuando el comando (s) en el cuerpo del comando
for
cambia el contenido del directorio enumerado (árbol)?
Supongamos que tenemos el directorio
D:/data
con el siguiente contenido:
file1.txt
file2.txt
file3.txt
La salida de
for %F in ("*.txt") do echo %F
cuando se ejecuta en dicho directorio reflejará obviamente la lista anterior.
Sin embargo, ¿cuál es la salida del bucle
for
cuando un comando en el cuerpo
for
modifica el contenido del directorio?
Por ejemplo, uno de los archivos de la lista se elimina, digamos
file3.txt
, antes de que se
file3.txt
.
¿O si se crea un nuevo archivo, como
file4.txt
, antes de completar el ciclo?
¿Cómo se comporta
for /R
en ese contexto?
Supongamos que hay varios subdirectorios
sub1
,
sub2
,
sub3
, cada uno de los cuales contiene la lista de archivos anterior;
for /R
está actualmente iterando a través de
sub2
,
sub1
ya se ha procesado, pero
sub3
aún no;
los contenidos de
sub1
y
sub3
se cambian en ese punto (cuando actualmente se camina por
sub2
como se mencionó);
¿Qué se enumerará entonces?
Supongo que el cambio del contenido de
sub1
no será reconocido, pero ¿qué pasa con
sub3
?
Finalmente, ¿hay una diferencia en el comportamiento de
for
o
for /R
cuando se ejecuta en el símbolo del sistema o desde un archivo por lotes?
¿Y hay diferencias en las diferentes versiones de Windows?
Nota:
Vea también mi
pregunta similar
sobre el comando
forfiles
.