Ok. Cercherò di essere il più chiaro possibile per non essere frainteso ...
In Windows file batch un nome di variabile dovrebbe iniziare con una lettera e può includere qualsiasi carattere valido, dove caratteri validi sono: # $ '() * +, -.? @ [] _ `{} ~ oltre a lettere e cifre.
Ciò significa che dal punto di vista di cmd.exe, SET NORMAL_NAME=123
corrisponde esattamente a SET A#$'()*+,[email protected][\]_{}~=123
e corrisponde a SET VECTOR[1]=123
; tutti e tre sono variabili normali. In questo modo, spetta a voi a scrivere i nomi delle variabili in forma di elementi di un array:
In questo modo, echo %elem[2]%
mostrerà Second one
.
Se si desidera utilizzare un'altra variabile come indice, è necessario sapere che la sostituzione di variabili racchiusi tra i simboli per cento dai loro valori viene analizzato da sinistra a destra; ciò significa che:
set i=2
echo %elem[%i%]%
non dà il risultato desiderato perché significa: mostra il valore della variabile elem[
, seguita da i
, seguito dal valore della variabile ]
.
Per risolvere questo problema è necessario utilizzare ritardata di espansione, cioè, inserire setlocal EnableDelayedExpansion
comando all'inizio, racchiudere variabili indice di simboli per cento, e racchiudono gli elementi dell'array in punti esclamativi:
setlocal EnableDelayedExpansion
set elem[1]=First element
set elem[2]=Second one
set elem[3]=The third one
set i=2
echo !elem[%i%]!
È può anche utilizzare i parametri dei comandi FOR come indici: for /L %%i in (1,1,3) do echo !elem[%%i]!
. Devi usare! Indice! per memorizzare i valori negli elementi dell'array quando l'indice viene modificato all'interno di FOR o IF: set elem[!index!]=New value
. Per ottenere il valore di un elemento quando l'indice cambia all'interno di FOR/IF, racchiudere l'elemento in simboli doppia percentuale e precedere il comando con call
. Ad esempio, per spostare una serie di elementi array quattro posizioni verso sinistra:
for /L %%i in (%start%,1,%end%) do (
set /A j=%%i + 4
call set elem[%%i]=%%elem[!j!]%%
)
Un altro modo per realizzare il processo precedente è di usare un ulteriore PER comando per cambiare l'espansione ritardata dell'indice da un parametro sostituibile equivalente e quindi utilizzare l'espansione ritardata per l'elemento dell'array. Questo metodo corre più veloce di chiamata precedente:
for /L %%i in (%start%,1,%end%) do (
set /A j=%%i + 4
for %%j in (!j!) do set elem[%%i]=!elem[%%j]!
)
In questo modo, il file batch si comporta come gestisce gli array. Penso che il punto importante qui non sia quello di discutere se Batch gestisce gli array o meno, ma il fatto che si possano gestire array in file Batch in modo equivalente ad altri linguaggi di programmazione.
@echo off
setlocal EnableDelayedExpansion
rem Create vector with names of days
set i=0
for %%d in (Sunday Monday Tuesday Wednesday Thrusday Friday Saturday) do (
set /A i=i+1
set day[!i!]=%%d
)
rem Get current date and calculate DayOfWeek
for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
set /A mm=10%%a %% 100, dd=10%%b %% 100, yy=%%c
)
if %mm% lss 3 set /A mm=mm+12, yy=yy-1
set /A a=yy/100, b=a/4, c=2-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10, jdn=c+dd+e+f-1523, dow=jdn %% 7 + 1
echo Today is !day[%dow%]!, %date%
Si noti che i valori di indice non sono limitati ai numeri, ma possono essere qualsiasi stringa che contiene caratteri validi; questo punto consente di definire ciò che in altri linguaggi di programmazione è chiamato associative arrays. A this answer c'è una spiegazione dettagliata del metodo utilizzato per risolvere un problema utilizzando un array associativo. Si noti inoltre che lo spazio è un carattere valido nei nomi delle variabili, quindi è necessario prestare attenzione a non inserire spazi nei nomi delle variabili che potrebbero passare inosservati.
Ho elaborato i motivi per cui devo utilizzare la notazione di array nei file batch allo this post.
In this post c'è un file batch che legge un file di testo e memorizza gli indici delle linee in un vettore, quindi esegue una ordinamento Buble di elementi vettoriali in base al contenuto della riga; il risultato equivalente è un ordinamento sui contenuti del file.
In this post è presente un'applicazione base di base dati relazionale in batch basata su indici memorizzati nei file.
In this post esiste in Batch un'applicazione completa con più elenchi concatenati che assembla una grande struttura dati presa da una sottodirectory e la visualizza sotto forma di comando TREE.
@MatteoItalia linux shell ce l'ha, powershell (basato su .net) ce l'ha, non so su Windows CScript.exe, ce l'ha o no? –
Questo dovrebbe essere divertente, ma invece è molto triste: la maggior parte delle risposte ha ottenuto 13 upvotes nonostante non abbiano risposto alla domanda. A mio avviso, una risposta che critica l'argomento solo con parole come "idiota", "terribilmente hackerata", "bizzarra" e termini simili non ha alcun valore. Nota che ** NON sto criticando le risposte né difendo Batch **. Non riesco a vedere qual è il presunto merito di quelle risposte per meritare una tale quantità di voti positivi! Mi chiedo se simili critiche alle risposte a Power Shell, script VBS, argomenti Phyton, Ruby, Pearl, PHP ecc. Ricevano quantità simili di upvotes ... :( – Aacini
Ben detto, Aacini. È importante ricordare che domande come questa coprono molti casi d'uso più semplici a cui è difficile trovare risposte, la risposta ha risposto a molte delle mie domande nello spirito originale di SO. – Shane