Популярный массив в скрипте DOS Batch Script
Как настроить переменную массива в пакетном скрипте DOS? Я хотел бы загрузить его со списком имен файлов для обработки. Мне бы очень хотелось сделать это как можно проще. Спасибо.
Как настроить переменную массива в пакетном скрипте DOS? Я хотел бы загрузить его со списком имен файлов для обработки. Мне бы очень хотелось сделать это как можно проще. Спасибо.
Я понял:
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, Массивы в пакете описывает, как эмулировать массивы в командной строке.
В статью включен пакетный файл 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%.
генерирует следующий вывод:
Это заполняет массив и печатает его
Вы можете использовать имена1 names2 names3, а не names[1] names[2] names[3], записывая имена!i! вместо names[!i!]. Он создает массив, генерируя имена переменных. Структура массива не существует пакетно. Но она такая же аккуратная, как и любая структура массива, и заполнение или вывод выглядит точно так же, как заполнение или вывод массива на нужном языке (который на самом деле имеет структуру массива!)
@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]!
)
вывод -
Некоторые объяснения -
setlocal enabledelayedexpansion enableextensions
с !var! вместо %var% необходимы для предотвращения нечетного поведения, чтобы переменные вели себя корректно, когда они находятся внутри FOR или IF. Странно с пакетными файлами. Смотрите раздел set /?
, где это упомянуто далее.
Это то, что заполняет массив, и довольно просто для любого, кто знает о массивах. Вы также можете сделать names[0]=bob
names[1]=tom
names[2]=joseph
, хотя одно из достоинств массива - это возможность заполнять массив циклом, что я и сделал.
c:\blah>a
bob
tom
joseph
c:\blah>
Здесь отображается массив. %%f если вы повторите его, то увидите, что он перейдет от 0 к последнему индексу массива, с шагом 1. Так же будут выведены имена[0] names[1] names[2]
for %%f in (bob, tom, joseph) do (
set /a i=!i!+1
set names[!i!]=%%f
)
set lastindex=!i!
Замените строки и буквы в тексте.
Попробуйте зациклиться, расширив текст до тела и заменив 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
)
Вы не можете настоящему делать массив в командной строке (а также на самом деле это не DOS, если только вы не работаете под Windows 3.1). Однако, вы можете выполнять обработку на основе множеств с помощью команды FOR.
Чтобы создать список обрабатываемых файлов, вы можете вручную создать текстовый файл для обработки или использовать команду dir /b <mask>
внутри цикла FOR.
Кое-что, чему я научился с FOR - в качестве курсора нужно использовать переменную SINGLE CHARACTER!
Для того, что вы хотите сделать, как насчет использования входной переменной для каждого имени файла, которую можно подобрать с помощью %1 %2 и т.д. переменных, например: mybat.bat file1.nam file2.nam и т.д..
Затем вы можете использовать эти переменные в цикле, но вам нужно использовать только %1 в качестве основного параметра, так как вы можете использовать SHIFT, чтобы привести другие переменные в %1 ‘позицию’, имея тест на ноль (конец переменных) с чем-то вроде IF “X%1” == “X” 0x2 & , например:
0x1 &
Просмотрите документацию 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
Если вы сохраните список файлов в filelist.txt, вы можете получить FOR
для чтения и обработки каждой строки файла, например
FOR /F "delims=|" %i IN (filelist.txt) DO @echo %i
для печати каждой строки файла (до первой “|” в строке). Если вы не укажете свой собственный разделитель, пробел и табуляция будут использоваться, так что если у ваших путей нет пробелов, вам нужно указать символ, который не будет отображаться в файле, чтобы получить полные строки).
Это небольшой отладочный файл, который я сделал некоторое время перейти к тестированию массива te из моей тик-так буксировки игры в BATCH / CMD. он может читать и писать в и из массива whitout собирается большой и сложный по коду.
использовать его просто:
Запись в массив
Чтение из массива
Код:
@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
В одном из ваших комментариев к ответу вы говорите, что
я занимаюсь разработкой, и в связи со сложной природой приложения каждый раз и хочу протестировать сборку (что часто бывает) мне приходится копировать пять файлов из каталога сборки в установочный бинарный каталог. Это становится утомительным. Сейчас у меня есть жестко закодированные имена файлов в моем пакетном скрипте, но я хотел бы поместить их в массив, чтобы сделать скрипт проще в обслуживании.
Я считаю, что вы ищете Makefile и, возможно, cygwin, чтобы дать вам приличную оболочку (bash, или что угодно с вашим вкусом).
Что-то вроде этого в пакетном файле? Выберите файл в папке. << есть комментарий, нет кода
: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
```.