Населення масиву в пакетному сценарії DOS


33

Як я можу встановити змінну масиву в пакетному сценарії DOS? Я хотів би завантажити його зі списком імен файлів для обробки. Я дуже хотів би зробити це максимально просто. Дякую.


1
Вам дійсно потрібно бути сумісним з DOS, або ви можете використовувати PowerShell?
Брайан Кноблауш,

1
Ви також можете використовувати vbscript досить легко для цього ...
JNK

@Brian: DOS обов'язковий. Ознайомтеся з рішенням, яке я розмістив.
Джим Fell

Якщо у вас немає волосся, ви, звичайно, повинні знати різницю між командним
рядком

Відповіді:


48

Я зрозумів це:

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%

Я робив щось подібне кілька років тому, тому це просто зайнялося з'ясуванням. (btw, я ненавиджу винаходити колесо.) Тепер, коли він розміщений тут, сподіваємось, і інші знайдуть це корисним.


1
Ну, я ніколи не знав, що ти можеш це зробити! Я спробував це і працює!
Linker3000

Це не може працювати в DOS. DOS не робить довгих імен файлів (лише 8.3), і, як я пам'ятаю, DOS також не робить лапок у файлових шляхах. У мене немає підключення MS-DOS, щоб дізнатися, чи підтримує він масиви за допомогою ()синтаксису.
CVn

3
Хоча це працює для ваших цілей, слід зазначити, що це насправді не масив. Це просто рядок, який розбивається на окремі елементи. Ви не можете посилатися на елементи безпосередньо, роблячи щось подібне FILE_LIST[0].
афорія

@ MichaelKjörling: FreeDOS може підтримувати LFN та імовірно котирування, тож, можливо, він це використовує?
Натан Туггі

@NathanTuggy Добре. Але все-таки було б краще в такому випадку, якби це було зроблено явно.
CVn

12

Так, ви можете робити масиви в пакетному режимі. Хоча вони не зовсім схожі на масиви на 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

1
це дивовижно і надихає .. Я щойно зробив відповідь, що спирається на це, і заповнює масив теж
барлоп

7

З блогу 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
добре, хоча ви не перерахували вміст array.bat, хоча я бачу, це трохи довго
барлоп

4

Це заповнює масив і друкує його

Ви можете використовувати names1 names2 name3, а не імена [1] імена [2] імена [3], написавши імена! I! замість імен [! 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]!
)

вихід-

c:\blah>a
bob
tom
joseph

c:\blah>

Деякі пояснення-

The setlocal enabledelayedexpansion enableextensionsз! Var! а не% 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. таким чином буде надруковано імена [0] імен [1] імена [2]

for /L %%f in (0,1,!lastindex!) do ( 
  echo !names[%%f]!
)

0

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

Потім ви можете використовувати ці змінні в циклі, але потрібно використовувати лише% 1 як основний параметр, оскільки ви можете використовувати SHIFT для приведення інших змінних у% 1 'позицію', маючи тест на null (кінець змінних) з чимось наприклад, якщо "X% 1" == "X"

наприклад:

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

0

Якщо ви збережете список файлів у filelist.txt, ви можете FORпрочитати та обробити кожен рядок файлу, наприклад

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

для друку кожного рядка файлу (до першого рядка "|" у рядку. Якщо ви не вказали власний роздільник, буде використано пробіл та вкладку, тому, якщо у ваших контурах немає пробілів, вам потрібно вказати символ які не з’являться у файлі для отримання повних рядків).


for / f - це фактично функція Windows 2000 та новіших версій. Це не в DOS.
wendy.krieger

0

В одному зі своїх коментарів до відповіді ви говорите:

Я займаюся розробкою, і через складний характер програми кожен раз, і я хочу протестувати збірку (що часто), мені доведеться скопіювати п'ять файлів з бінарного каталогу збірки в бінарний каталог установки. Це стає нудним. Зараз у мене імена файлів жорстко закодовані в мій пакетний сценарій, але я хотів би поставити їх у масив, щоб полегшити підтримку сценарію.

Я вважаю, що те, що ви шукаєте, - це Makefile, і, можливо, cygwin, щоб надати вам гідну оболонку (баш, або будь-який ваш смак).


0

Замініть рядки та літеру в тексті.

Спробуйте знайти цикл, розклавши текст до а для тіла та замінивши 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
)

0

Щось подібне у пакетному файлі? Виберіть файл у папці. << це коментар, немає коду

: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

0

Ви дійсно не можете зробити масив у командному рядку (а також це насправді не DOS, якщо ви не працюєте з Windows 3.1). Однак ви можете виконати обробку на основі набору за допомогою команди FOR.

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

Щось я навчився важко за допомогою FOR - вам потрібно використовувати змінну SINGLE CHARACTER як ваш курсор!


+1 ви коментуєте, що пояснення слід пояснити. Крім того, ви написали "вам потрібно використовувати змінну SINGLE CHARACTER як ваш курсор!" <- ти маєш на увазі як свій індекс не як курсор
барлоп

1
Також зауважте, що якщо це завантажувальний диск Win9X, це DOS (DOS 7). І Windows 9X все ще говорили, що він працює на DOS. І ви можете додати рядок, я думаю, що саме msdos.sys як bootscan = 0 і bootgui = 0 зупинив його завантаження у Windows та завантажився прямо у DOS-підказку.
барлоп

0

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

За замовчуванням для заданих ручок або просто файлів:

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

Або для рекурсивного:

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

або, лише для каталогів:

FOR /D %d DO ECHO %d

На жаль, всі ці варіанти є всеохоплюючими у відповідних сферах. Я займаюся розробкою, і через складний характер програми кожен раз, і я хочу протестувати збірку (що часто), мені доведеться скопіювати п'ять файлів з бінарного каталогу збірки в бінарний каталог установки. Це стає нудним. Зараз у мене імена файлів жорстко закодовані в мій пакетний сценарій, але я хотів би поставити їх у масив, щоб полегшити підтримку сценарію.
Джим Фелл

0

це невеликий файл налагодження, який я зробив деякий час, щоб перейти до тестування масиву з моєї гри "tic tac" в BATCH / CMD. він може читати і записувати в масив і з нього, не переходячи на великий і складний код.

з його допомогою просто:

Запис у масив

  1. надайте йому файл або змініть його, щоб імпортувати щось інше.
  2. дайте назву масиву.
  3. і твоє зроблено.

Читання з масиву

  1. Укажіть розмір масиву або його частини, яку ви хочете прочитати.
  2. Введіть ім'я масиву з %% a в імені
  3. і твоє зроблено.

Код:

@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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.