Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

How can I setup an array variable in a DOS batch script? I would like to load it with a list of file names to process. I really would like to keep this as simple as possible. Thank you.

share|improve this question
1  
Do you really need to be DOS compatible, or can you use PowerShell? –  Brian Knoblauch Sep 21 '10 at 19:48
1  
You can also use vbscript pretty easily for this... –  JNK Sep 21 '10 at 20:19
    
@Brian: DOS is required. Check out the solution I posted. –  Jim Fell Sep 21 '10 at 21:42
    
If you have no hair then you should certainly know the difference between the command prompt and DOS –  barlop Aug 29 at 11:13

11 Answers 11

up vote 29 down vote accepted

I figured it out:

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%

I did something like this several years ago, so it just took some figuring out. (btw, I hate reinventing the wheel.) Now that it's posted here, hopefully others will find it useful too.

share|improve this answer
1  
Well, I never knew you could do that! I tried it and it works! –  Linker3000 Sep 21 '10 at 21:24
    
This cannot possibly work in DOS. DOS doesn't do long file names (only 8.3), and as I recall, DOS doesn't do quotes in file paths either. I don't have a MS-DOS installation handy to see if it supports arrays using a () syntax. –  Michael Kjörling May 2 at 9:48
    
While this does work for your purpose, it should be noted that it is not really an array. It is just a string that is being split into individual elements. You cannot reference the elements directly by doing something like FILE_LIST[0]. –  aphoria Aug 29 at 14:10

From Jakash3's Blog, Arrays in Batch describes how to emulate arrays in the command prompt.

A batch file named array.bat is included in the article, that contains a library of functions used to handle arrays. You will need to select the the text in the article and paste it inside the bat file.

For example, the following test script:

@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%.

generates the following output:

image

share|improve this answer
1  
ok though you haven't listed the contents of array.bat though I see it is a bit long –  barlop Nov 5 '13 at 15:27

Yes you can do arrays in batch. While they aren't exactly like arrays in C or VB, you CAN do it:

@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
share|improve this answer
    
that is awesome and inspring.. i've just done an answer that builds on that and populates the array too –  barlop Aug 29 at 11:52

You can't really do an array in the command prompt (and also it's not really DOS unless you are running Windows 3.1). However, you can do set-based processing with the FOR command.

To create the list of files to be processed, you can manually create a text file to be processed, or use the dir /b <mask> command inside the FOR loop.

Something I learned the hard way with FOR - you need to use a SINGLE CHARACTER variable as your cursor!

share|improve this answer
2  
Thanks for the pointless, unexplained downvote! –  JNK Sep 21 '10 at 23:32
    
+1 you comment that a downvote should be explained. Also, you wrote "you need to use a SINGLE CHARACTER variable as your cursor!" <-- you mean as your index not as your cursor –  barlop Aug 29 at 11:16
    
Also note that if it's a Win9X boot disk that's DOS (DOS 7). And Windows 9X was still said to run on DOS. And you could add a line to I think it was msdos.sys like bootscan=0 and bootgui=0 that'd stop it booting into Windows and boot straight to a DOS prompt. –  barlop Aug 29 at 13:34

Check out the Microsfot documentation for the FOR batch command. You can use FOR to iterate over a set of directories, files in a directory, or files in a directory and all of its sub-directories.

By default FOR handle set or just files:

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

Or, for recursive:

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

or, for just direcotries:

FOR /D %d DO ECHO %d
share|improve this answer
    
Unfortunately, all of those options are all-inclusive to their respective scopes. I am doing development work, and due to the complex nature of the application every time and want to test a build (which is often) I have to copy five files from the build binary directory to the install binary directory. This gets tedious. Right now, I have the file names hard-coded into my batch script, but I would like to put them into an array to make the script easier to maintain. –  Jim Fell Sep 21 '10 at 19:21

For what you want to do, how about using an input variable for each file name, which you can pick up with the %1 %2 etc. variables eg: mybat.bat file1.nam file2.nam etc..

You can then use these variables in a loop but only need to use %1 as the main parameter as you can use SHIFT to bring the other variables into the %1 'position', having a test for null (end of variables) with something like IF "X%1" == "X"

eg:

:LOOP
IF "X%1" == "X" GOTO DONE
COPY %1 C:\TARGET.DIR
SHIFT
GOTO LOOP
:DONE
share|improve this answer

If you save the list of files to filelist.txt, you can get FOR to read and process each line of the file, such as

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

to print each line of a file (up to the first "|" in the line. If you don't specify your own delimiter, space and tab will be used, so unless your paths have no spaces, you need to specify a character that will not appear in the file to get complete lines).

share|improve this answer
    
for /f is actually a windows 2000 and later feature. It is not in DOS. –  wendy.krieger May 2 at 11:12

In one of your comments to an answer you say,

I am doing development work, and due to the complex nature of the application every time and want to test a build (which is often) I have to copy five files from the build binary directory to the install binary directory. This gets tedious. Right now, I have the file names hard-coded into my batch script, but I would like to put them into an array to make the script easier to maintain.

I believe that what you are looking for is a Makefile, and possibly cygwin to give you a decent shell (bash, or whatever your flavour).

share|improve this answer

Replace strings and letter in text.

Try for loop by expanding text to a for body and replacing var with var. Drag and drop text file so %1 is user input by invoking set command.

@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
)
share|improve this answer

Something like this in a batch file? Select a file in a folder. << is comment, no code

: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
share|improve this answer

This populates an array and prints it

You could use names1 names2 names3, rather than names[1] names[2] names[3] by writing names!i! instead of names[!i!]. It produces the array by generating variable names. There isn't an array structure in batch. But it is as neat as any array structure, and populating or printing looks exactly like how one would populate or print an array in a proper language(that actually has the array structure!)

@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]!
)

the output-

c:\blah>a
bob
tom
joseph

c:\blah>

Some explanation-

The setlocal enabledelayedexpansion enableextensions with the !var! rather than %var% is necessary to prevent odd behavior, so that variables behave properly when within a FOR or an IF. It's an oddity with batch files. See set /? where that is mentioned further.

This is what populates the array, and is pretty straight forward to anybody that knows about arrays. You could also do names[0]=bob names[1]=tom names[2]=joseph though one of the beauties of an array is the ability to populate an array with a loop, which is what i've done here.

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

This displays the array. %%f if you echo it you'd see will go from 0 to the last index of the array, in steps of 1. so will print names[0] names[1] names[2]

for /L %%f in (0,1,!lastindex!) do ( 
  echo !names[%%f]!
)
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.