Заполнение массива в DOS Batch Script

123934
Jim Fell

Как я могу установить переменную массива в пакетном скрипте DOS? Я хотел бы загрузить его со списком имен файлов для обработки. Я действительно хотел бы сделать это как можно более простым. Спасибо.

33
Вам действительно нужно совместимость с DOS или вы можете использовать PowerShell? Brian Knoblauch 14 лет назад 1
Вы также можете довольно легко использовать vbscript для этого ... JNK 14 лет назад 1
@Brian: DOS требуется. Проверьте решение, которое я отправил. Jim Fell 14 лет назад 0
Если у вас нет волос, вы должны знать разницу между командной строкой и DOS barlop 10 лет назад 0

12 ответов на вопрос

48
Jim Fell

Я понял:

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% 

Я сделал что-то подобное несколько лет назад, так что мне потребовалось определиться. (кстати, я ненавижу заново изобретать колесо.) Теперь, когда оно опубликовано здесь, надеюсь, другие найдут его полезным.

Ну, я никогда не знал, что ты можешь сделать это! Я попробовал, и это работает! Linker3000 14 лет назад 1
Это не может работать в DOS. DOS не делает длинные имена файлов (только 8.3), и, насколько я помню, DOS также не делает кавычек в путях к файлам. У меня нет удобной установки MS-DOS, чтобы увидеть, поддерживает ли она массивы с использованием синтаксиса `()`. a CVn 10 лет назад 0
Хотя это работает для вашей цели, следует отметить, что это не совсем массив. Это просто строка, которая разбивается на отдельные элементы. Вы не можете ссылаться на элементы напрямую, делая что-то вроде `FILE_LIST [0]`. aphoria 10 лет назад 3
@ MichaelKjörling: FreeDOS [может поддерживать LFNs) (http://www.freedos.org/software/?prog=lfndos) и предположительно цитаты, так что, может быть, он использует это? Nathan Tuggy 9 лет назад 0
@NathanTuggy Хорошая мысль. Тем не менее, было бы лучше в этом случае, если бы это было сделано явно. a CVn 9 лет назад 0
@ MichaelKjörling: Определенно. (И реально кажется более вероятным, что это на самом деле cmd.exe, но никто не знает.) Nathan Tuggy 9 лет назад 0
@NathanTuggy Хорошо, OP * действительно * указал в комментариях к вопросу явно, что "DOS требуется." DOS! = Командная строка Windows (и * особенно * программист должен знать это ...). Когда-то они были одним и тем же, но это было два десятилетия назад ... a CVn 9 лет назад 0
12
Patrick Jackson

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 
это удивительно и вдохновляюще .. я только что сделал ответ, который основывается на этом и заполняет массив тоже barlop 10 лет назад 1
7
harrymc

В блоге Jakash3 Arrays in Batch описано, как эмулировать массивы в командной строке.

Пакетный файл с именем array.bat включен в статью, которая содержит библиотеку функций, используемых для обработки массивов. Вам нужно будет выделить текст в статье и вставить его в файл bat.

Например, следующий тестовый скрипт:

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

генерирует следующий вывод:

image

хорошо, хотя вы не перечислили содержимое array.bat, хотя я вижу, что это немного долго barlop 11 лет назад 1
3
barlop

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]! ) 
1
JNK

Вы не можете действительно сделать массив в командной строке (а также это на самом деле не DOS, если вы не работаете в Windows 3.1). Однако вы можете выполнить обработку на основе множеств с помощью команды FOR.

Чтобы создать список файлов для обработки, вы можете вручную создать текстовый файл для обработки или использовать dir /b <mask>команду внутри цикла FOR.

Что-то, чему я научился с помощью FOR - вам нужно использовать переменную SINGLE CHARACTER в качестве курсора!

+1 Вы комментируете, что отрицательный голос должен быть объяснен. Кроме того, вы написали "вам нужно использовать переменную SINGLE CHARACTER в качестве курсора!" <- вы имеете в виду как ваш индекс, а не как курсор barlop 10 лет назад 0
Также обратите внимание, что если это загрузочный диск Win9X, то это DOS (DOS 7). А Windows 9X все еще говорили, что он работает на DOS. И вы можете добавить строку, я думаю, что это msdos.sys, такой как bootscan = 0 и bootgui = 0, который остановит загрузку в Windows и загрузится прямо в командной строке DOS. barlop 10 лет назад 1
0
heavyd

Ознакомьтесь с документацией Microsoft по пакетной команде FOR . Вы можете использовать FOR для перебора набора каталогов, файлов в каталоге или файлов в каталоге и всех его подкаталогах.

По умолчанию FOR обрабатывает набор или просто файлы:

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

Или для рекурсии:

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

или только для каталогов:

FOR /D %d DO ECHO %d 
К сожалению, все эти варианты являются всеобъемлющими для соответствующих областей. Я занимаюсь разработкой, и из-за сложной природы приложения каждый раз и хочу протестировать сборку (что часто бывает), мне приходится копировать пять файлов из двоичного каталога сборки в установочный двоичный каталог. Это становится утомительным. Прямо сейчас у меня есть имена файлов, жестко запрограммированные в моем пакетном скрипте, но я бы хотел поместить их в массив, чтобы облегчить поддержку скрипта. Jim Fell 14 лет назад 0
0
Linker3000

Что вы хотите сделать, как насчет использования входной переменной для каждого имени файла, которую вы можете выбрать с помощью переменных% 1% 2 и т. Д., Например: mybat.bat file1.nam file2.nam и т. Д.

Затем вы можете использовать эти переменные в цикле, но вам нужно только использовать% 1 в качестве основного параметра, так как вы можете использовать SHIFT, чтобы перевести другие переменные в% 1 «позицию», имея тест на ноль (конец переменных) с чем-то например, если "X% 1" == "X"

например:

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

Если вы сохраните список файлов в filelist.txt, вы сможете FORпрочитать и обработать каждую строку файла, например:

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

чтобы напечатать каждую строку файла (до первого «|» в строке. Если вы не укажете свой собственный разделитель, будут использоваться пробел и табуляция, поэтому, если в ваших путях нет пробелов, вам нужно указать символ это не появится в файле, чтобы получить полные строки).

for / f на самом деле является функцией Windows 2000 и более поздних версий. Это не в DOS. wendy.krieger 10 лет назад 0
0
lorenzog

В одном из ваших комментариев к ответу вы говорите:

Я занимаюсь разработкой, и из-за сложной природы приложения каждый раз и хочу протестировать сборку (что часто бывает), мне приходится копировать пять файлов из двоичного каталога сборки в установочный двоичный каталог. Это становится утомительным. Прямо сейчас у меня есть имена файлов, жестко запрограммированные в моем пакетном скрипте, но я бы хотел поместить их в массив, чтобы облегчить поддержку скрипта.

Я считаю, что вы ищете Makefile и, возможно, Cygwin, чтобы дать вам приличную оболочку (bash или любой другой ваш вкус).

0
mordex

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 ) 

Похожие вопросы