การเติม Array ในสคริปต์ DOS Batch


33

ฉันจะตั้งค่าตัวแปรอาเรย์ในสคริปต์แบตช์ DOS ได้อย่างไร ฉันต้องการโหลดด้วยรายการชื่อไฟล์ที่จะประมวลผล ฉันอยากจะทำให้มันเรียบง่ายที่สุดเท่าที่จะทำได้ ขอขอบคุณ.


1
คุณจริงๆจะต้อง DOS ที่เข้ากันได้หรือคุณสามารถใช้ PowerShell?
Brian Knoblauch

1
นอกจากนี้คุณยังสามารถใช้ vbscript ได้อย่างง่ายดายสำหรับสิ่งนี้ ...
JNK

@Brian: ต้องการ DOS ลองดูโซลูชันที่ฉันโพสต์
Jim Fell

หากคุณไม่มีผมคุณควรทราบถึงความแตกต่างระหว่างพรอมต์คำสั่งและดอสอย่างแน่นอน
barlop

คำตอบ:


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 ดอสไม่ได้ทำชื่อไฟล์ยาว ๆ (เฉพาะ 8.3) และอย่างที่ฉันจำได้ว่าดอสไม่ทำเครื่องหมายคำพูดในเส้นทางไฟล์เช่นกัน ฉันไม่มีการติดตั้ง MS-DOS เพื่อดูว่ามันรองรับอาร์เรย์โดยใช้()ไวยากรณ์หรือไม่
CVn

3
ขณะนี้ใช้งานได้ตามวัตถุประสงค์ของคุณควรสังเกตว่าไม่ใช่อาร์เรย์จริงๆ มันเป็นเพียงแค่สตริงที่ถูกแบ่งออกเป็นองค์ประกอบของแต่ละบุคคล FILE_LIST[0]คุณไม่สามารถอ้างอิงองค์ประกอบโดยตรงโดยการทำสิ่งที่ต้องการ
aphoria

@ MichaelKjörling: FreeDOS สามารถรองรับ LFNและราคาน่าจะเป็นดังนั้นเขาอาจจะใช้มันได้หรือไม่
Nathan Tuggy

@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
ที่ยอดเยี่ยมและ inspring .. ฉันเพิ่งทำคำตอบที่สร้างบนนั้นและเติมอาเรย์ด้วย
barlop

7

จากบล็อกของ Jakash3 อาร์เรย์ในแบทช์จะอธิบายวิธีจำลองอาร์เรย์ในพรอมต์คำสั่ง

ชุดไฟล์ชื่อ array.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 แต่ฉันเห็นว่ามันค่อนข้างยาว
barlop

4

สิ่งนี้จะเติมอาร์เรย์และพิมพ์

คุณสามารถใช้ names1 names2 names3 แทนชื่อ [1] names [2] names [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>

คำอธิบายบางอย่าง -

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 หากคุณ echo คุณจะเห็นว่าจะเปลี่ยนจาก 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 'ตำแหน่ง' โดยมีการทดสอบค่าว่าง (จุดสิ้นสุดของตัวแปร) ด้วยบางอย่าง เช่นถ้า "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) อย่างไรก็ตามคุณสามารถทำการประมวลผลแบบ set-based ด้วยคำสั่ง FOR

ในการสร้างรายการไฟล์ที่จะประมวลผลคุณสามารถสร้างไฟล์ข้อความด้วยตนเองเพื่อประมวลผลหรือใช้dir /b <mask>คำสั่งภายในลูป FOR

บางสิ่งที่ฉันเรียนรู้วิธีที่ยากด้วย FOR - คุณต้องใช้ตัวแปรตัวละครเดียวเป็นเคอร์เซอร์ของคุณ!


+1 คุณแสดงความคิดเห็นว่าควรมีการอธิบาย downvote นอกจากนี้คุณเขียนว่า "คุณต้องใช้ตัวแปรตัวละครเดียวเป็นเคอร์เซอร์ของคุณ!" <- คุณหมายถึงว่าเป็นดัชนีของคุณไม่ใช่เคอร์เซอร์
barlop

1
โปรดทราบด้วยว่าหากเป็นดิสก์สำหรับบูต Win9X นั่นคือ DOS (DOS 7) และ Windows 9X ยังคงบอกว่าทำงานบน DOS และคุณสามารถเพิ่มบรรทัดให้ฉันคิดว่ามันเป็น msdos.sys เช่น bootscan = 0 และ bootgui = 0 ที่หยุดการบูทเข้าสู่ Windows และบูตตรงไปที่ DOS prompt
barlop

0

ตรวจสอบเอกสารไมโครซอฟท์ในคำสั่งสำหรับชุด คุณสามารถใช้ FOR เพื่อวนซ้ำชุดของไดเรกทอรีไฟล์ในไดเรกทอรีหรือไฟล์ในไดเรกทอรีและไดเรกทอรีย่อยทั้งหมด

โดยค่าเริ่มต้นสำหรับการจัดการการตั้งค่าหรือเพียงแค่ไฟล์:

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

หรือสำหรับการเรียกซ้ำ:

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

หรือสำหรับไดเรกทอรีเพียง:

FOR /D %d DO ECHO %d

น่าเสียดายที่ตัวเลือกทั้งหมดนั้นรวมอยู่ในขอบเขตที่เกี่ยวข้อง ฉันทำงานพัฒนาและเนื่องจากลักษณะที่ซับซ้อนของแอปพลิเคชันทุกครั้งและต้องการทดสอบการสร้าง (ซึ่งมักจะ) ฉันต้องคัดลอกห้าไฟล์จากไดเรกทอรีไบนารีสร้างไปยังไดเรกทอรีไบนารีติดตั้ง เรื่องนี้น่าเบื่อ ตอนนี้ฉันมีชื่อไฟล์ที่เขียนโค้ดลงในสคริปต์ชุดงานของฉันแล้ว แต่ฉันต้องการที่จะใส่ลงในอาร์เรย์เพื่อให้สคริปต์รักษาได้ง่ายขึ้น
Jim Fell

0

นี่เป็นไฟล์ debug ขนาดเล็กที่ฉันทำในขณะที่ไปทดสอบอาร์เรย์ te จากเกม tic tac tow ของฉันใน 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.