Mảng dân cư trong DOS Batch Script


33

Làm cách nào tôi có thể thiết lập một biến mảng trong tập lệnh bó DOS? Tôi muốn tải nó với một danh sách các tên tệp để xử lý. Tôi thực sự muốn giữ điều này đơn giản nhất có thể. Cảm ơn bạn.


1
Bạn có thực sự cần phải tương thích với DOS hay bạn có thể sử dụng PowerShell không?
Brian Knoblauch

1
Bạn cũng có thể sử dụng vbscript khá dễ dàng cho việc này ...
JNK

@Brian: Bắt buộc phải có DOS. Kiểm tra các giải pháp tôi đã đăng.
Jim Fell

Nếu bạn không có tóc thì chắc chắn bạn nên biết sự khác biệt giữa dấu nhắc lệnh và DOS
barlop

Câu trả lời:


48

Tôi đã hiểu rồi:

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%

Tôi đã làm một cái gì đó như thế này vài năm trước, vì vậy nó chỉ cần tìm ra một số. (btw, tôi ghét phát minh lại bánh xe.) Bây giờ nó được đăng ở đây, hy vọng những người khác cũng sẽ thấy nó hữu ích.


1
Chà, tôi không bao giờ biết bạn có thể làm điều đó! Tôi đã thử nó và nó hoạt động!
Linker3000

Điều này có thể không thể làm việc trong DOS. DOS không thực hiện tên tệp dài (chỉ 8.3) và như tôi nhớ, DOS cũng không thực hiện trích dẫn trong đường dẫn tệp. Tôi không có sẵn bản cài đặt MS-DOS để xem nó có hỗ trợ mảng không bằng ()cú pháp.
một CVn

3
Mặc dù điều này không hoạt động cho mục đích của bạn, nhưng cần lưu ý rằng nó không thực sự là một mảng. Nó chỉ là một chuỗi đang được chia thành các yếu tố riêng lẻ. Bạn không thể tham chiếu các yếu tố trực tiếp bằng cách làm một cái gì đó như FILE_LIST[0].
aphoria

@ MichaelKjorling: FreeDOS có thể hỗ trợ các LFN và có lẽ là trích dẫn, vì vậy có lẽ anh ấy đang sử dụng nó?
Nathan Tuggy

@NathanTuggy Điểm tốt. Tuy nhiên, sẽ tốt hơn trong trường hợp đó nếu nó được làm rõ ràng.
CVn

12

Có bạn có thể làm mảng trong lô. Mặc dù chúng không chính xác như các mảng trong C hoặc VB, bạn CÓ THỂ làm điều đó:

@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
đó là điều tuyệt vời và trẻ con .. tôi vừa hoàn thành một câu trả lời dựa trên đó và cũng điền vào mảng đó
barlop

7

Từ Blog của Jakash3, Mảng trong Batch mô tả cách mô phỏng các mảng trong dấu nhắc lệnh.

Một tệp bó có tên là Array.bat được bao gồm trong bài viết, có chứa một thư viện các hàm được sử dụng để xử lý các mảng. Bạn sẽ cần phải chọn văn bản trong bài viết và dán nó vào trong tập tin bat.

Ví dụ: tập lệnh kiểm tra sau:

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

tạo đầu ra sau:

hình ảnh


1
ok mặc dù bạn chưa liệt kê nội dung của mảng.bat mặc dù tôi thấy nó hơi dài
barlop

4

Điều này điền vào một mảng và in nó

Bạn có thể sử dụng tên1 tên2 tên3, thay vì tên [1] tên [2] tên [3] bằng cách viết tên! I! thay vì tên [! i!]. Nó tạo ra mảng bằng cách tạo tên biến. Không có một cấu trúc mảng trong lô. Nhưng nó gọn gàng như bất kỳ cấu trúc mảng nào, và việc điền hoặc in trông giống hệt như cách người ta cư trú hoặc in một mảng bằng một ngôn ngữ phù hợp (thực sự có cấu trúc mảng!)

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

đầu ra-

c:\blah>a
bob
tom
joseph

c:\blah>

Một số giải thích-

Các setlocal enabledelayedexpansion enableextensionsvới! Var! thay vì% var% là cần thiết để ngăn chặn hành vi kỳ quặc, để các biến hoạt động đúng khi ở trong FOR hoặc IF. Đó là một sự kỳ lạ với các tập tin hàng loạt. Xem set /?nơi đó được đề cập thêm.

Đây là những gì điền vào mảng và khá dễ dàng cho bất kỳ ai biết về mảng. Bạn cũng có thể làm names[0]=bob names[1]=tom names[2]=josephmặc dù một trong những nét đẹp của mảng là khả năng điền vào một mảng bằng một vòng lặp, đó là những gì tôi đã làm ở đây.

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

Điều này sẽ hiển thị các mảng. %% f nếu bạn lặp lại nó bạn sẽ thấy sẽ đi từ 0 đến chỉ mục cuối cùng của mảng, trong các bước của 1. vì vậy sẽ in tên [0] tên [1] tên [2]

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

0

Đối với những gì bạn muốn làm, làm thế nào về việc sử dụng một biến đầu vào cho mỗi tên tệp, mà bạn có thể chọn với các biến% 1% 2, v.v., ví dụ: mybat.bat file1.nam file2.nam, v.v.

Sau đó, bạn có thể sử dụng các biến này trong một vòng lặp nhưng chỉ cần sử dụng% 1 làm tham số chính vì bạn có thể sử dụng SHIFT để đưa các biến khác vào vị trí% 1 ', kiểm tra null (kết thúc biến) với thứ gì đó như NẾU "X% 1" == "X"

ví dụ:

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

0

Nếu bạn lưu danh sách các tệp vào filelist.txt, bạn có thể FORđọc và xử lý từng dòng của tệp, chẳng hạn như

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

để in từng dòng của tệp (tối đa "|" đầu tiên trong dòng. Nếu bạn không chỉ định dấu phân cách của riêng mình, khoảng trắng và tab sẽ được sử dụng, vì vậy trừ khi đường dẫn của bạn không có khoảng trắng, bạn cần chỉ định một ký tự sẽ không xuất hiện trong tập tin để có được dòng hoàn chỉnh).


for / f thực sự là một tính năng của windows 2000 trở lên. Nó không có trong DOS.
wendy.krieger

0

Trong một trong những bình luận của bạn cho một câu trả lời bạn nói,

Tôi đang làm công việc phát triển và do tính chất phức tạp của ứng dụng mỗi lần và muốn kiểm tra bản dựng (thường là) tôi phải sao chép năm tệp từ thư mục nhị phân xây dựng sang thư mục nhị phân cài đặt. Điều này trở nên tẻ nhạt. Ngay bây giờ, tôi có các tên tệp được mã hóa cứng vào tập lệnh bó của mình, nhưng tôi muốn đặt chúng vào một mảng để làm cho tập lệnh dễ bảo trì hơn.

Tôi tin rằng những gì bạn đang tìm kiếm là một Makefile, và có thể là Cygwin để cung cấp cho bạn một vỏ tốt (bash, hoặc bất cứ hương vị nào của bạn).


0

Thay thế chuỗi và chữ trong văn bản.

Thử vòng lặp bằng cách mở rộng văn bản thành phần thân và thay thế var bằng var. Kéo và thả tệp văn bản để% 1 là đầu vào của người dùng bằng cách gọi lệnh 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

Một cái gì đó như thế này trong một tập tin hàng loạt? Chọn một tập tin trong một thư mục. << là bình luận, không có mã

: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

Bạn thực sự không thể thực hiện một mảng trong dấu nhắc lệnh (và cũng không thực sự là DOS trừ khi bạn đang chạy Windows 3.1). Tuy nhiên, bạn có thể thực hiện xử lý dựa trên thiết lập bằng lệnh FOR.

Để tạo danh sách các tệp cần xử lý, bạn có thể tự tạo một tệp văn bản cần xử lý hoặc sử dụng dir /b <mask>lệnh bên trong vòng lặp FOR.

Một cái gì đó tôi đã học được một cách khó khăn với FOR - bạn cần sử dụng biến SINGLE CHARACTER làm con trỏ của mình!


+1 bạn nhận xét rằng một downvote nên được giải thích. Ngoài ra, bạn đã viết "bạn cần sử dụng biến SINGLE CHARACTER làm con trỏ!" <- ý bạn là chỉ mục của bạn không phải là con trỏ của bạn
barlop

1
Cũng lưu ý rằng nếu đó là đĩa khởi động Win9X thì đó là DOS (DOS 7). Và Windows 9X vẫn được cho là chạy trên DOS. Và bạn có thể thêm một dòng vào Tôi nghĩ đó là msdos.sys như bootscan = 0 và bootgui = 0 sẽ dừng nó khởi động vào Windows và khởi động thẳng đến dấu nhắc của DOS.
barlop

0

Kiểm tra tài liệu của Microsoft về lệnh FOR batch . Bạn có thể sử dụng FOR để lặp lại một tập hợp các thư mục, tệp trong một thư mục hoặc các tệp trong một thư mục và tất cả các thư mục con của nó.

Theo mặc định, tay cầm FOR được đặt hoặc chỉ các tệp:

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

Hoặc, cho đệ quy:

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

hoặc, chỉ cho các thư mục:

FOR /D %d DO ECHO %d

Thật không may, tất cả các tùy chọn đó đều bao gồm tất cả các phạm vi tương ứng của chúng. Tôi đang làm công việc phát triển và do tính chất phức tạp của ứng dụng mỗi lần và muốn kiểm tra bản dựng (thường là) tôi phải sao chép năm tệp từ thư mục nhị phân xây dựng sang thư mục nhị phân cài đặt. Điều này trở nên tẻ nhạt. Ngay bây giờ, tôi có các tên tệp được mã hóa cứng vào tập lệnh bó của mình, nhưng tôi muốn đặt chúng vào một mảng để làm cho tập lệnh dễ bảo trì hơn.
Jim Fell

0

đây là một tệp gỡ lỗi nhỏ mà tôi đã thực hiện để kiểm tra mảng te từ trò chơi kéo tic tac của tôi trong BATCH / CMD. nó có thể đọc và ghi vào và từ một mảng trắng sẽ trở nên lớn và phức tạp trên mã.

sử dụng nó rất đơn giản:

Viết vào một mảng

  1. cung cấp cho nó một tập tin hoặc sửa đổi nó để nhập một số khác.
  2. đặt tên cho mảng
  3. và bạn đã hoàn thành

Đọc từ một mảng

  1. Cho kích thước của mảng hoặc một phần của nó bạn muốn đọc.
  2. Đặt tên của mảng với %% a trong tên
  3. và bạn đã hoàn thành

Mã số:

@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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.