Popolamento della matrice in uno script batch per DOS
Come posso impostare una variabile array in uno script batch DOS? Vorrei caricarlo con un elenco di nomi di file da elaborare. Vorrei davvero mantenerlo il più semplice possibile. Grazie.
Come posso impostare una variabile array in uno script batch DOS? Vorrei caricarlo con un elenco di nomi di file da elaborare. Vorrei davvero mantenerlo il più semplice possibile. Grazie.
L'ho capito:
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%
Ho fatto qualcosa di simile diversi anni fa, quindi ci è voluto solo un po’ per capirlo. (btw, odio reinventare la ruota.) Ora che è stato postato qui, speriamo che anche altri lo trovino utile.
Sì, è possibile fare array in batch. Anche se non sono esattamente come gli array in C o VB, si può fare:
@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
Dal blog di Jakash3, Arrays in Batch descrive come emulare gli array nel prompt dei comandi.
Nell'articolo è incluso un file batch chiamato array.bat, che contiene una libreria di funzioni usate per gestire gli array. Dovrete selezionare il testo dell'articolo e incollarlo all'interno del file bat.
Per esempio, il seguente script di prova:
@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 il seguente output:
Questo popola un array e lo stampa
Si potrebbe usare names1 names2 names3, piuttosto che names[1] names[2] names[3] scrivendo names!i! invece di names[!i!]. Produce l'array generando nomi di variabili. Non c'è una struttura di array in batch. Ma è ordinata come qualsiasi struttura di array, e il popolamento o la stampa sembra esattamente come si popolerebbe o stamperebbe un array in un linguaggio appropriato (che ha effettivamente la struttura dell'array!)
@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]!
)
l'output-
c:\blah>a
bob
tom
joseph
c:\blah>
Qualche spiegazione-
Lo setlocal enabledelayedexpansion enableextensions
con il !var! piuttosto che %var% è necessario per prevenire comportamenti strani, in modo che le variabili si comportino correttamente quando all'interno di un FOR o un IF. È una stranezza con i file batch. Vedi set /?
dove viene menzionato ulteriormente.
Questo è ciò che popola l'array, ed è abbastanza semplice per chiunque conosca gli array. Si potrebbe anche fare names[0]=bob
names[1]=tom
names[2]=joseph
anche se una delle bellezze di un array è la capacità di popolare un array con un ciclo, che è quello che ho fatto qui.
for %%f in (bob, tom, joseph) do (
set /a i=!i!+1
set names[!i!]=%%f
)
set lastindex=!i!
Questo visualizza l'array. %%f se fate l'echo vedrete che andrà da 0 all'ultimo indice dell'array, in passi di 1. Quindi stamperà nomi[0] nomi[1] nomi[2]
for /L %%f in (0,1,!lastindex!) do (
echo !names[%%f]!
)
Sostituire stringhe e lettere nel testo.
Prova il ciclo for espandendo il testo in un corpo for e sostituendo var con var. Trascina il file di testo in modo che %1 sia l'input dell'utente invocando il 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
)
Non potete realmente fare un array nel prompt dei comandi (e inoltre non è veramente DOS a meno che non stiate usando Windows 3.1). Tuttavia, potete fare elaborazioni basate su set con il comando FOR.
Per creare la lista di file da elaborare, potete creare manualmente un file di testo da elaborare, o usare il comando dir /b <mask>
dentro il ciclo FOR.
Qualcosa che ho imparato a mie spese con il FOR - devi usare una variabile CARATTERA SINGOLA come cursore!
Per quello che vuoi fare, che ne dici di usare una variabile di input per ogni nome di file, che puoi prendere con le variabili %1 %2 ecc. es: mybat.bat file1.nam file2.nam ecc.
Puoi poi usare queste variabili in un ciclo ma hai solo bisogno di usare %1 come parametro principale poiché puoi usare SHIFT per portare le altre variabili nella “posizione” di %1, avendo un test per null (fine delle variabili) con qualcosa come IF “X%1” == “X”
es:
:LOOP
IF "X%1" == "X" GOTO DONE
COPY %1 C:\TARGET.DIR
SHIFT
GOTO LOOP
:DONE
Controllate la documentazione Microsoft sul comando batch FOR . Potete usare FOR per iterare su un insieme di directory, file in una directory, o file in una directory e tutte le sue sottodirectory.
Per default FOR gestisce l'insieme o solo i file:
FOR %f IN (*.txt) DO ECHO %f
Oppure, per ricorsivo:
FOR /R %f IN (*.txt) DO ECHO %f
oppure, per sole directory:
FOR /D %d DO ECHO %d
Se salvate la lista dei file in filelist.txt, potete ottenere FOR
per leggere ed elaborare ogni linea del file, come
FOR /F "delims=|" %i IN (filelist.txt) DO @echo %i
per stampare ogni linea di un file (fino al primo “|” nella linea. Se non specificate il vostro delimitatore, verranno usati spazio e tabulazione, quindi, a meno che i vostri percorsi non abbiano spazi, dovete specificare un carattere che non apparirà nel file per ottenere linee complete).
Questo è un piccolo file di debug che ho fatto un po’ di tempo fa per testare l'array del mio gioco tic tac tow in BATCH / CMD. può leggere e scrivere da e verso un array senza diventare troppo grande e complicato nel codice.
usarlo è semplice:
Scrivere su un array
Leggere da un array
Codice:
@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
In uno dei tuoi commenti a una risposta dici,
Sto facendo un lavoro di sviluppo, e a causa della natura complessa dell'applicazione ogni volta e voglio testare una build (che è spesso) devo copiare cinque file dalla directory binaria di build alla directory binaria di installazione. Questo diventa noioso. In questo momento, ho i nomi dei file hard-coded nel mio script batch, ma vorrei metterli in un array per rendere lo script più facile da mantenere.
Credo che quello che stai cercando sia un Makefile, e possibilmente cygwin per darti una shell decente (bash, o qualunque sia il tuo gusto).
Qualcosa del genere in un file batch? Seleziona un file in una cartella. << ‖ è un commento, nessun codice
: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