Matriz poblada en secuencia de comandos de lote DOS


33

¿Cómo puedo configurar una variable de matriz en un script por lotes de DOS? Me gustaría cargarlo con una lista de nombres de archivo para procesar. Realmente me gustaría mantener esto lo más simple posible. Gracias.


1
¿ Realmente necesitas ser compatible con DOS o puedes usar PowerShell?
Brian Knoblauch

1
También puede usar vbscript con bastante facilidad para esto ...
JNK

@Brian: se requiere DOS. Mira la solución que publiqué.
Jim Fell

Si no tiene cabello, entonces debería saber la diferencia entre el símbolo del sistema y DOS
barlop

Respuestas:


48

Me lo imaginé:

set FILE_LIST=(file1.dll file2.exe file3.dll file4.dll file5.dll)

set BIN_PATH="C:\Program Files\My App Folder\bin"
set BAK_PATH="C:\Program Files\My App Folder\bin\Backups"
set DEV_PATH="C:\My Dev Path\bin\Debug"

for %%i in %FILE_LIST% do copy %BIN_PATH%\%%i %BAK_PATH%
for %%i in %FILE_LIST% do copy %DEV_PATH%\%%i %BIN_PATH%

Hice algo como esto hace varios años, así que solo me costó un poco descubrirlo. (por cierto, odio reinventar la rueda). Ahora que está publicado aquí, espero que otros también lo encuentren útil.


1
Bueno, ¡nunca supe que podías hacer eso! Lo probé y funciona!
Linker3000

Esto no puede funcionar en DOS. DOS no hace nombres largos de archivo (solo 8.3), y como recuerdo, DOS tampoco hace comillas en las rutas de archivo. No tengo una instalación de MS-DOS a mano para ver si admite matrices que usan una ()sintaxis.
un CVn

3
Si bien esto funciona para su propósito, debe tenerse en cuenta que no es realmente una matriz. Es solo una cadena que se divide en elementos individuales. No puede hacer referencia a los elementos directamente haciendo algo como FILE_LIST[0].
aphoria

@ MichaelKjörling: FreeDOS puede admitir LFN y presumiblemente citas, así que ¿tal vez está usando eso?
Nathan Tuggy el

@NathanTuggy Buen punto. Aún así, sería mejor en ese caso si se hiciera explícito.
un CVn

12

Sí, puedes hacer matrices en lote. Si bien no son exactamente como matrices en C o VB, PUEDES hacerlo:

@echo off
setlocal enabledelayedexpansion

set  arrayline[0]=############
set  arrayline[1]=#..........#
set  arrayline[2]=#..........#
set  arrayline[3]=#..........#
set  arrayline[4]=#..........#
set  arrayline[5]=#..........#
set  arrayline[6]=#..........#
set  arrayline[7]=#..........#
set  arrayline[8]=#..........#
set  arrayline[9]=#..........#
set arrayline[10]=#..........#
set arrayline[11]=#..........#
set arrayline[12]=############

::read it using a FOR /L statement
for /l %%n in (0,1,12) do (
echo !arrayline[%%n]!
)
pause

1
eso es increíble e inspring ... acabo de hacer una respuesta que se basa en eso y también llena la matriz
barlop

7

Desde el blog de Jakash3, Arrays in Batch describe cómo emular arrays en el símbolo del sistema.

Un archivo por lotes llamado array.bat se incluye en el artículo, que contiene una biblioteca de funciones utilizadas para manejar matrices. Deberá seleccionar el texto en el artículo y pegarlo dentro del archivo bat.

Por ejemplo, el siguiente script de prueba:

@echo off
set book[0]=Avatar
set book[1]=The Green Mile
set book[2]=The Count of Monte Cristo
call array.bat add book Babo
call array.bat len book length
echo I have %length% books you can borrow.
echo Pick one:
echo.
echo 0) Avatar
echo 1) The Green Mile
echo 2) The Count of Monte Cristo
echo 3) Babo
echo.
set /p pick=
call array.bat getitem book %pick% title
echo.
echo You picked %title%.

genera el siguiente resultado:

imagen


1
ok aunque no hayas enumerado el contenido de array.bat aunque veo que es un poco largo
barlop

4

Esto llena una matriz y la imprime

¡Puede usar nombres1 nombres2 nombres3, en lugar de nombres [1] nombres [2] nombres [3] escribiendo nombres! I! en lugar de nombres [! i!]. Produce la matriz generando nombres de variables. No hay una estructura de matriz en lote. Pero es tan ordenado como cualquier estructura de matriz, y rellenar o imprimir se ve exactamente como se llenaría o imprimiría una matriz en un lenguaje adecuado (¡que en realidad tiene la estructura de matriz!)

@echo off
setlocal enabledelayedexpansion enableextensions

set i=-1

for %%f in (bob, tom, joseph) do (
 set /a i=!i!+1
 set names[!i!]=%%f
)
set lastindex=!i!

for /L %%f in (0,1,!lastindex!) do ( 
  echo !names[%%f]!
)

La salida-

c:\blah>a
bob
tom
joseph

c:\blah>

Alguna explicación

El setlocal enabledelayedexpansion enableextensionscon el! Var! en lugar de% var% es necesario para evitar un comportamiento extraño, de modo que las variables se comporten correctamente cuando están dentro de un FOR o un IF. Es una rareza con los archivos por lotes. Vea set /?dónde se menciona más adelante.

Esto es lo que puebla la matriz, y es bastante sencillo para cualquiera que sepa sobre matrices. También podría hacerlo, names[0]=bob names[1]=tom names[2]=josephaunque una de las bellezas de una matriz es la capacidad de llenar una matriz con un bucle, que es lo que he hecho aquí.

for %%f in (bob, tom, joseph) do (
 set /a i=!i!+1
 set names[!i!]=%%f
)
set lastindex=!i!

Esto muestra la matriz. %% f si lo repite, verá que irá de 0 al último índice de la matriz, en los pasos de 1. así que imprimirá nombres [0] nombres [1] nombres [2]

for /L %%f in (0,1,!lastindex!) do ( 
  echo !names[%%f]!
)

0

Para lo que desea hacer, ¿qué tal usar una variable de entrada para cada nombre de archivo, que puede elegir con las variables% 1% 2 etc., por ejemplo: mybat.bat file1.nam file2.nam, etc.

Luego puede usar estas variables en un bucle, pero solo necesita usar% 1 como parámetro principal, ya que puede usar SHIFT para llevar las otras variables a la 'posición'% 1, con una prueba de nulo (final de variables) con algo como SI "X% 1" == "X"

p.ej:

:LOOP
IF "X%1" == "X" GOTO DONE
COPY %1 C:\TARGET.DIR
SHIFT
GOTO LOOP
:DONE

0

Si guarda la lista de archivos en filelist.txt, puede FORleer y procesar cada línea del archivo, como

FOR /F "delims=|" %i  IN (filelist.txt) DO @echo %i

para imprimir cada línea de un archivo (hasta el primer "|" en la línea. Si no especifica su propio delimitador, se utilizarán espacios y tabulaciones, por lo que a menos que sus rutas no tengan espacios, debe especificar un carácter que no aparecerá en el archivo para obtener líneas completas).


for / f es en realidad una característica de Windows 2000 y posterior. No está en DOS.
wendy.krieger

0

En uno de sus comentarios a una respuesta, usted dice:

Estoy haciendo trabajo de desarrollo, y debido a la naturaleza compleja de la aplicación cada vez y quiero probar una compilación (que a menudo es así) tengo que copiar cinco archivos del directorio binario de compilación al directorio binario de instalación. Esto se vuelve tedioso. En este momento, tengo los nombres de archivo codificados en mi script por lotes, pero me gustaría ponerlos en una matriz para que el script sea más fácil de mantener.

Creo que lo que está buscando es un Makefile, y posiblemente cygwin para darle un caparazón decente (bash, o cualquier sabor que tenga).


0

Reemplazar cadenas y letras en el texto.

Pruebe bucle expandiendo el texto a un cuerpo for y reemplazando var con var. Arrastre y suelte el archivo de texto para que% 1 sea introducido por el usuario invocando el comando set.

@echo off
setlocal EnableDelayedExpansion
set /p a= enter letter to change:
set /p b= letter to change to:
set /p input=<%1
for /f %%c in ("!input:~!") do (
set "code=!input:%a%=%b%!"
echo !code!>myfile.txt
)

0

¿Algo así en un archivo por lotes? Seleccione un archivo en una carpeta. << es comentario, sin código

:selectapk
SETLOCAL ENABLEDELAYEDEXPANSION      << DELAYED EXPANSION on for counter in For loop
SET /A MAXITEM=0
Echo.
Echo Found these APK files in "add_apk_here" folder.
Echo.
For %%a in (add_apk_here/*.apk) do (
 Set /A MAXITEM+=1
 Set MENUITEM!MAXITEM!=%%a        << Fill n local env vars, one for each file, called MENUITEM1...n
 Echo    !MAXITEM!. %%a
)
Echo.
If !MAXITEM!==0 Echo No APK in "add_apk_here" folder & call :delay & Goto start   << No apk files then go back
SET /P CHOICE=Select APK to work on: 
SET MENUITEM=!MENUITEM%CHOICE%!      << Get the stored filename from MENUITEMx
SETLOCAL DISABLEDELAYEDEXPANSION     << Very important for next ENDLOCAL that doesn't like the delayedexpansion var
ENDLOCAL & SET apk=%MENUITEM%        << put the local MENUITEM var into the global apk var
goto start

:delay
REM %1 like Call :delay 5
SETLOCAL
SET N=%1
If Not Defined N Set N=2
Ping -n %N% -w 1000 127.255.255.255 > nul
ENDLOCAL
Exit /b

0

Realmente no puede hacer una matriz en el símbolo del sistema (y tampoco es realmente DOS a menos que esté ejecutando Windows 3.1). Sin embargo, puede hacer un procesamiento basado en conjuntos con el comando FOR.

Para crear la lista de archivos para procesar, puede crear manualmente un archivo de texto para procesar, o usar el dir /b <mask>comando dentro del bucle FOR.

Algo que aprendí por las malas con FOR: ¡necesitas usar una variable de CARÁCTER SIMPLE como cursor!


+1 comentas que se debe explicar un voto negativo. Además, escribió "¡necesita usar una variable de CARÁCTER ÚNICO como cursor!" <- quieres decir como tu índice, no como tu cursor
barlop

1
También tenga en cuenta que si se trata de un disco de arranque Win9X, es DOS (DOS 7). Y todavía se decía que Windows 9X se ejecutaba en DOS. Y podría agregar una línea a Creo que fue msdos.sys como bootscan = 0 y bootgui = 0 lo que impediría que se iniciara en Windows y se iniciara directamente en un indicador de DOS.
barlop

0

Consulte la documentación de Microsoft en el comando por lotes FOR . Puede usar FOR para iterar sobre un conjunto de directorios, archivos en un directorio o archivos en un directorio y todos sus subdirectorios.

Por defecto FOR maneja conjuntos o solo archivos:

FOR %f IN (*.txt) DO ECHO %f

O, para recursivo:

FOR /R %f IN (*.txt) DO ECHO %f

o, solo para directorios:

FOR /D %d DO ECHO %d

Desafortunadamente, todas esas opciones incluyen todos sus ámbitos respectivos. Estoy haciendo trabajo de desarrollo, y debido a la naturaleza compleja de la aplicación cada vez y quiero probar una compilación (que a menudo es así) tengo que copiar cinco archivos del directorio binario de compilación al directorio binario de instalación. Esto se vuelve tedioso. En este momento, tengo los nombres de archivo codificados en mi script por lotes, pero me gustaría ponerlos en una matriz para que el script sea más fácil de mantener.
Jim Fell

0

Este es un pequeño archivo de depuración que hice un tiempo para probar la matriz de mi juego de tic tac tow en BATCH / CMD. puede leer y escribir desde y hacia una matriz sin llegar a ser grande y complicado en el código.

usarlo es simple:

Escribir en una matriz

  1. darle un archivo o modificarlo para importar algo más.
  2. dale un nombre a la matriz.
  3. y listo

Leer desde una matriz

  1. Indique el tamaño de la matriz o parte de ella que desea leer.
  2. Ponga el nombre de la matriz con %% a en el nombre
  3. y listo

Código:

@echo off
setlocal EnableDelayedExpansion

set ID=0

::              Reader                   ::
:: It reads the file called input.txt    ::
:: and stores it in a new variable that  ::
:: for everytime it goes over it it is a ::
:: new ID (Slot in the array).           ::

For /F %%A in (input.txt) do ( 
    set /a ID=ID+1
    set Input!ID!= %%A

    echo !ID! : %%A
)


::             Writer                     ::
:: this is to read all Slots in the array ::
:: and puts it on the screen.             ::

for /L %%a in (1,1,!ID!) do (
    echo !Input%%a!
)
pause>nul
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.