Windows batch: เรียกมากกว่าหนึ่งคำสั่งใน FOR loop?


124

เป็นไปได้ไหมในไฟล์แบตช์ของ Windows ที่จะเรียกคำสั่งมากกว่าหนึ่งคำสั่งในลูปเดียว FORตัวอย่างเช่นฉันต้องการพิมพ์ชื่อไฟล์และหลังจากลบแล้ว:

@ECHO OFF
FOR /r %%X IN (*.txt) DO (ECHO %%X DEL %%X)
REM the line above is invalid syntax.

ฉันรู้ว่าในกรณีนี้ฉันสามารถแก้ปัญหาได้โดยทำสองวงสำหรับลูปที่แตกต่างกัน: อันหนึ่งสำหรับแสดงชื่อและอีกอันสำหรับการลบไฟล์ แต่เป็นไปได้ไหมที่จะทำในลูปเดียวเท่านั้น

คำตอบ:


117
FOR /r %%X IN (*) DO (ECHO %%X & DEL %%X)

2
อันที่จริงฉันคิดว่าวงเล็บไม่จำเป็น for %i in (1 2 3) do echo %i & echo fooพิมพ์สิ่งที่ฉันคาดหวัง: "1", "foo", "2", "foo", "3", "foo" (แยกบรรทัดกัน)
bk1e

ไม่ควรจะ&&เป็นมากกว่า&?
jww

9
@jww &&จะล้มเหลวหากคำสั่งแรกล้มเหลว&จะดำเนินการคำสั่งที่สองโดยไม่คำนึงถึง
yyny

หากโซลูชันนี้ทำให้เกิดข้อผิดพลาดทางไวยากรณ์ให้ตรวจสอบว่าคุณมีพาเรนที่ไม่ใช้ Escape ระหว่างDO-parens หรือไม่ คุณอาจจะหลบหนีพวกเขาโดยผนวก^กับพวกเขา
КонстантинВан

199

การใช้&คำสั่งสั้น ๆ ทำได้ดี แต่บรรทัดเดียวนั้นยาวมากอย่างรวดเร็ว เมื่อเป็นเช่นนั้นให้เปลี่ยนไปใช้ไวยากรณ์แบบหลายบรรทัด

FOR /r %%X IN (*.txt) DO (
    ECHO %%X
    DEL %%X
)

ตำแหน่ง(และ)เรื่อง DOต้องวางวงเล็บกลมหลังไว้ในบรรทัดเดียวกันมิฉะนั้นไฟล์แบตช์จะไม่ถูกต้อง

ดูif /?|find /V ""รายละเอียด


12
โซลูชันนี้ดูสะอาดและน่าอ่าน ฉันจะเตือนโปรแกรมเมอร์ที่ใช้โซลูชันนี้ด้วยว่าDOต้องไม่วางวงเล็บกลมหลังจากบรรทัดถัดไปมิฉะนั้นจะเบรคไฟล์แบตช์ ในโค้ดเมื่อฉันเขียน for loop ฉันมักจะวางวงเล็บปีกกา{ในบรรทัดถัดไป
Marco Demaio

2
นอกจากนี้โปรดระวังหากคำสั่งที่ซ้อนกันของคุณมีวงเล็บอยู่ (ตัวอย่างเช่น "echo Something something (something else)" EDIT: ah ดูคำตอบของ bk1e :)
Tim Barrass

31

SilverSkin และ Anders ถูกต้องทั้งคู่ คุณสามารถใช้วงเล็บเพื่อดำเนินการหลายคำสั่ง อย่างไรก็ตามคุณต้องตรวจสอบให้แน่ใจว่าคำสั่งต่างๆ (และพารามิเตอร์) ไม่มีวงเล็บ cmdค้นหาวงเล็บปิดแรกอย่างตะกละตะกลามแทนที่จะจัดการชุดวงเล็บที่ซ้อนกันอย่างสง่างาม สิ่งนี้อาจทำให้บรรทัดคำสั่งที่เหลือไม่สามารถแยกวิเคราะห์หรืออาจทำให้วงเล็บบางส่วนถูกส่งผ่านไปยังคำสั่ง (เช่นDEL myfile.txt))

วิธีแก้ปัญหานี้คือการแยกเนื้อหาของลูปออกเป็นฟังก์ชันแยกกัน โปรดทราบว่าคุณอาจต้องกระโดดไปรอบ ๆ ส่วนของฟังก์ชันเพื่อหลีกเลี่ยงการ "หลุด" เข้าไป

FOR /r %%X IN (*.txt) DO CALL :loopbody %%X
REM Don't "fall through" to :loopbody.
GOTO :EOF

:loopbody
ECHO %1
DEL %1
GOTO :EOF

3
ในขณะที่เราอยู่ในหัวข้อนั้น% X ไม่เคยถูกต้องเมื่อจัดการกับชื่อไฟล์ให้ใช้ "% ~ X" เสมอ (ในตัวอย่างของคุณที่นี่คุณสามารถหลีกเลี่ยงการใช้% * ในฟังก์ชันย่อยได้)
แอนเดอร์

1
นั่นเป็นจุดที่ดีจริงๆ C:\Program Files (x86)เป็นตัวอย่างที่ดีของเส้นทางที่แสดงให้เห็นถึงปัญหาทั้งสองเป็น
bk1e
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.