variable read batch bat batch-file windows-vista

batch-file - windows batch read command output to variable



archivos de proceso por lotes de windows: variable de ajuste en for loop (3)

No estoy seguro de si esto está oficialmente documentado, pero puede simular una expansión demorada utilizando la declaración de call :

@echo off FOR /R %%X IN (*.txt) DO ( set temp=%%~nX call echo directory %%temp:~0,7%% )

Doblar los signos de porcentaje difiere la sustitución de variables a la segunda evaluación. Sin embargo, la demora en la expansión es mucho más directa.

Tengo varios archivos con el mismo esquema de nombres. Como muestra, cuatro archivos se llaman "num_001_001.txt", "num_002_001.txt", "num_002_002.txt", "num_002_003.txt"

El primer conjunto de números representa de qué "paquete" es, y el segundo conjunto de números simplemente se usa para distinguirlos entre sí. Entonces en este ejemplo tenemos un archivo en el paquete 001 y tres archivos en el paquete 002.

Estoy escribiendo un comando de lote de Windows Vista para tomar todos los archivos y moverlos a sus propios directorios, donde cada directorio representa un paquete diferente. Así que quiero mover todos los archivos para el paquete 001 al directorio "001" y todos para 002 al directorio "002"

He escrito con éxito un script que iterará sobre todos los archivos txt y los repetirá. También escribí un script que moverá un archivo a otra ubicación, y también creará el directorio si no existe.

Ahora supongo que tendré que usar subcadenas, así que utilicé la sintaxis% var: ~ start, end% para obtenerlas. Como prueba, escribí esto para verificar que realmente puedo extraer la subcadena y crear un directorio condicionalmente

@echo off set temp=num_001_001.txt NOT IF exist %temp:~0,7%/ mkdir %temp:~0,7%

Y funciona. Estupendo.
Entonces agregué el bucle for al mismo.

@echo off FOR /R %%X IN (*.txt) DO ( set temp=%%~nX echo directory %temp:~0,7% )

Pero este es mi resultado:

directory num_002 directory num_002 directory num_002 directory num_002

¿Qué pasa? ¿Vista no admite la reasignación de variables en cada iteración? Los cuatro archivos están en mi directorio, y uno de ellos debe crear num_001. Puse diferentes archivos con 003 004 005 y todo fue el nombre del último paquete. Supongo que algo anda mal con la forma en que estoy configurando las cosas.

Tengo diferentes soluciones para hacer el trabajo, pero estoy confundido por qué un concepto tan simple no funcionaría.


Otra solución es mover el cuerpo del bucle for a una subrutina y call .

@echo off FOR /R %%X IN (*.txt) DO call :body %%X goto :eof :body set temp=%~n1 echo directory %temp:~0,7% goto :eof

¿Por qué hacer esto? Una razón es que el procesador de comandos de Windows es codicioso acerca de los paréntesis, y los resultados pueden ser sorprendentes. Por lo general me encuentro con esto cuando se eliminan las referencias de variables que contienen C:/Program Files (x86) .

Si el procesador de comandos de Windows era menos codicioso, el siguiente código imprimirá One (1) Two (2) o nada en absoluto:

@echo off if "%1" == "yes" ( echo 1 (One) echo 2 (Two) )

Sin embargo, eso no es lo que hace. O imprime 1 (One 2 (Two) , que falta a ) , o imprime 2 (Two) . El procesador de comandos interpreta el ) después de One como el final del cuerpo de la instrucción if , trata el segundo echo como si estuviera fuera de la instrucción if e ignora el final ) .


Su problema es que la variable se reemplaza cuando el procesador por lotes lee el comando for, antes de que se ejecute.

Prueba esto:

SET temp=Hello, world! CALL yourbatchfile.bat

Y verá Hola impreso 5 veces.

La solución es la expansión demorada; primero debes habilitarlo y luego usar !temp! en lugar de %temp% :

@echo off SETLOCAL ENABLEDELAYEDEXPANSION FOR /R %%X IN (*.txt) DO ( set temp=%%~nX echo directory !temp:~0,7! )

Mira here para más detalles.