ช่วงหลายช่วงของไฟล์ตามลำดับคำใน zsh


24

ฉันต้องการระบุช่วงของไฟล์ (ตามลำดับพจนานุกรม) ด้วยจำนวนเต็มสองจำนวน (เช่น 2 ถึง 57) ใน zsh โดยการวนรอบ

ตัวอย่างเช่น: "เลือกไฟล์ 2 ถึง 57 ตามลำดับคำศัพท์ภายใต้พา ธ ที่ตรงกับรูปแบบการวนลูป

ฉันคิดว่าการใช้วงเล็บเหลี่ยมจะทำได้

 for x in /foo/bar/*[2-57]; do print $x; done

แต่เห็นได้ชัดว่า zsh คิดว่าฉันขอไฟล์2ไป5(หรือสิ่งที่ต้องการ) แทนไฟล์ไป2 57ความคิดใด ๆ ฉันจะทำสิ่งนี้ได้อย่างไร

คำตอบ:


30

[2-57]เป็นชุดตัวอักษรประกอบด้วย2, 3, 4, 5และ7ใน zsh และทุกสัญลักษณ์แทนอื่น ๆ และไวยากรณ์ regexp ออกมี รูปแบบ glob ของคุณ*[2-57]ตรงกับชื่อไฟล์ทุกตัวที่มีอักขระตัวสุดท้ายเป็นหนึ่งในห้าหลัก

ผมคิดว่าคุณกำลัง misremembering ไวยากรณ์ของรอบคัดเลือก[m,n] glob ตัวระบุ Glob จะอยู่ในวงเล็บเสมอที่ส่วนท้ายของรูปแบบและตัวคั่นช่วงคือเครื่องหมายจุลภาค รูปแบบ*([2,57])ขยายไปยังการแข่งขัน 2, 3, …, 57th ลำดับการขยายเริ่มต้นคือพจนานุกรม (ด้วยเวทมนตร์พิเศษบางอย่างเพื่อเรียงลำดับหมายเลขตามลำดับตัวเลขหากnumeric_glob_sortตั้งค่าตัวเลือก) คุณสามารถควบคุมมันด้วยตัวระบุคุณสมบัติoหรือOglob (เช่น*(om[2,57])จับคู่ไฟล์ล่าสุด 57 ไฟล์ยกเว้นไฟล์ล่าสุดหนึ่งไฟล์)

for x in /foo/bar/*([2,57]); do print $x; done

ไม่ใช่สิ่งที่คุณขอ แต่เกี่ยวข้องและอาจเป็นประโยชน์กับผู้อ่านในอนาคต: หากคุณต้องการแจกแจงไฟล์ 2 ถึง 57 ว่ามีอยู่หรือไม่คุณสามารถใช้นิพจน์วงเล็บปีกกาได้ คุณลักษณะนี้มีอยู่ใน bash และ ksh

echo hello{2..57}

และถ้าคุณต้องการจับคู่ไฟล์ที่มีชื่อมีตัวเลขระหว่าง 2 ถึง 57 คุณสามารถใช้รูปแบบ<2-57>ได้ นี่คือเฉพาะสำหรับ zsh

$ ls
file1 file2 file3 file57 file58
$ echo file<2-57>
file2 file3 file57

โปรดทราบว่ารูปแบบเช่น*<2-57>นั้นมีแนวโน้มที่จะไม่ทำตามที่คุณคาดไว้เพราะ*สามารถจับคู่ตัวเลขได้เช่นกัน ยกตัวอย่างเช่นfile58ตรง*<2-57>กับfile5การจับคู่*และส่วนหนึ่งของ8การจับคู่<2-57>ส่วน รูปแบบ*[^0-9]<2-57>หลีกเลี่ยงปัญหานี้


คุณพูดถูก ฉันกำลังหมุนรอบคัดเลือกรอบคัดเลือกอย่างไม่ถูกต้อง ขอบคุณสำหรับคำอธิบายอย่างระมัดระวัง
Amelio Vazquez-Reina

ข้อความนี้ทำให้ฉันสับสนเล็กน้อย: if you want to enumerate files 2 to 57 whether they exist or not, you can use a range brace expression. หากไฟล์ไม่มีอยู่และไม่มีข้อมูลตรงกันการขยายรั้งจะรู้ได้อย่างไรว่าจะขยายอย่างไร (มันจะขยายตัวแตกต่างจากรอบคัดเลือกรอบตัวอย่างไร)
Amelio Vazquez-Reina

2
@intrpc ขยายไปfoo{8..11}bar foo8bar foo9bar foo10bar foo11barการขยายตัวเล็กน้อยนี้ไม่เกี่ยวข้องกับชื่อไฟล์ ในทำนองเดียวกันการขยายfoo{eight,nine,ten,eleven}bar fooeightbar fooninebar footenbar fooelevenbarนี่คือการขยายรั้งใน ksh / bash / zsh
Gilles 'หยุดความชั่วร้าย'

6

แต่เห็นได้ชัดว่า zsh คิดว่าฉันกำลังขอไฟล์ 2 ถึง 5 (หรืออะไรทำนองนั้น) แทนที่จะเป็นไฟล์ 2 ถึง 57 ความคิดใดทำไม

เนื่องจาก[]วงเล็บระบุรายการของอักขระที่ตรงกัน(ซึ่งอาจเป็นตัวเลข) ไม่ใช่ตัวเลขที่ตีความทางคณิตศาสตร์ รูปแบบดังกล่าวจับคู่กับอักขระตัวเดียว รายการสามารถมีช่วง แต่เป็นตัวเลขหรือตัวอักษร [2-57]ตรงกับขยายไป"ตัวเลขทั้งหมดในช่วง 2-5 และ 7"

ในการจับคู่ตัวเลขตั้งแต่ 2 ถึง 57 จะเป็นการง่ายกว่าถ้าใช้นิพจน์ลำดับแทนรูปแบบกลม (หรือร่วมกับ):

for x in /foo/bar/*{2..57}; do print $x; done

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


ขอบคุณ @rozcietrzewiacz! ฉันควรคิดเกี่ยวกับเรื่องนี้ ไฟล์ของฉันมีตัวเลขอยู่ในนั้นดังนั้นฉันจึงคิดว่า[]กำลังพิมพ์สิ่งต่าง ๆ ตามลำดับ ..
Amelio Vazquez-Reina

คำอธิบายของคุณ[2-57]ถูกต้อง แต่ฉันไม่คิดว่า{2..57}(นั่นคือสิ่งที่คุณหมายถึงใช่ไหม) มีความเกี่ยวข้องกับสิ่งที่ intrpc ต้องการทำซึ่งก็คือ“ เลือกไฟล์ 2 ถึง 57 ตามลำดับพจนานุกรม”
Gilles 'หยุดความชั่วร้าย'

ขอบคุณสำหรับการแก้ไข (เวลาเข้านอนฉันเดา) และคุณพูดถูก - ฉันลืมเรื่องส่วนคำศัพท์
rozcietrzewiacz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.