Как я могу установить переменную массива в пакетном скрипте DOS? Я хотел бы загрузить его со списком имен файлов для обработки. Я действительно хотел бы сделать это как можно более простым. Спасибо.
12 ответов
Я понял:
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%
Я сделал что-то подобное несколько лет назад, так что мне потребовалось определиться. (кстати, я ненавижу изобретать велосипед.) Теперь, когда он размещен здесь, надеюсь, другие найдут его полезным.
Да, вы можете делать массивы в пакетном режиме. Хотя они не совсем похожи на массивы в C или VB, вы МОЖЕТЕ сделать это:
@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
В блоге 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%.
генерирует следующий вывод:
Это заполняет массив и печатает его
Вы можете использовать names1 names2 names3, а не names [1] names [2] names [3] при написании имён!я! вместо имен [!я!]. Это производит массив, генерируя имена переменных. В пакете нет структуры массива. Но он такой же аккуратный, как и любая структура массива, и заполнение или печать выглядят точно так же, как можно было бы заполнить или напечатать массив на соответствующем языке (который на самом деле имеет структуру массива!)
@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]!
)
выход-
c:\blah>a
bob
tom
joseph
c:\blah>
Некоторое объяснение
setlocal enabledelayedexpansion enableextensions
с помощью!вар! а не% var% необходим для предотвращения нечетного поведения, чтобы переменные вели себя правильно, находясь внутри FOR или IF. Это странность с пакетными файлами. Смотрите set /?
где это упоминается далее.
Это то, что заполняет массив, и довольно просто для любого, кто знает о массивах. Вы также можете сделать names[0]=bob
names[1]=tom
names[2]=joseph
хотя одна из красот массива - это возможность заполнять массив циклом, что я и сделал здесь.
for %%f in (bob, tom, joseph) do (
set /a i=!i!+1
set names[!i!]=%%f
)
set lastindex=!i!
Это отображает массив. %% f если вы откроете его, вы увидите, что он перейдет от 0 к последнему индексу массива, с шагами 1. так же будет напечатано names [0] names [1] names [2]
for /L %%f in (0,1,!lastindex!) do (
echo !names[%%f]!
)
Вы не можете действительно сделать массив в командной строке (а также это на самом деле не DOS , если вы не работаете в Windows 3.1). Однако вы можете выполнить обработку на основе множеств с помощью команды FOR.
Чтобы создать список файлов для обработки, вы можете вручную создать текстовый файл для обработки или использовать команду dir /b <mask>
внутри цикла FOR.
Что-то, чему я научился с помощью FOR - вам нужно использовать переменную SINGLE CHARACTER в качестве курсора!
это небольшой файл отладки, который я сделал некоторое время, чтобы протестировать массив из моей игры Tic Tac Tow в BATCH / CMD. он может читать и записывать в и из массива без больших и сложных кодов.
используя это просто:
Запись в массив
- дайте ему файл или измените его, чтобы импортировать что-то еще.
- дать массиву имя.
- и вы сделали.
Чтение из массива
- Укажите размер массива или его части, который вы хотите прочитать.
- Введите имя массива с %% a в имени
- и вы сделали.
Код:
@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
Ознакомьтесь с документацией 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
Что вы хотите сделать, как насчет использования входной переменной для каждого имени файла, которую вы можете выбрать с помощью переменных% 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
Если вы сохраните список файлов в filelist.txt, вы можете получить FOR
для чтения и обработки каждой строки файла, например:
FOR /F "delims=|" %i IN (filelist.txt) DO @echo %i
печатать каждую строку файла (до первого символа «|» в строке. Если вы не укажете свой собственный разделитель, будут использованы пробел и табуляция, поэтому, если в ваших путях нет пробелов, вам нужно указать символ, который не будет отображаться в файле, чтобы получить полные строки).
В одном из ваших комментариев к ответу вы говорите:
Я занимаюсь разработкой, и из-за сложной природы приложения каждый раз и хочу протестировать сборку (что часто бывает), мне приходится копировать пять файлов из двоичного каталога сборки в установочный двоичный каталог. Это становится утомительным. Прямо сейчас у меня есть имена файлов, жестко запрограммированные в моем пакетном скрипте, но я бы хотел поместить их в массив, чтобы облегчить поддержку скрипта.
Я считаю, что вы ищете Makefile и, возможно, Cygwin, чтобы дать вам приличную оболочку (bash или любой другой ваш вкус).
Заменить строки и буквы в тексте.
Попробуйте цикл, расширив текст до for и заменив var на var. Перетащите текстовый файл, чтобы% 1 был введен пользователем, вызвав команду 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
)
Как то так в командном файле? Выберите файл в папке. << комментарий, без кода
: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