รายการไฟล์ที่มีหมายเลขในช่วงที่ระบุ


16

ฉันมีชุดของไฟล์ในไดเรกทอรีที่มีหมายเลขดังนี้:

file1.txt
file2.txt
...
file30.txt
...

ตอนนี้ฉันต้องการเรียกใช้คำสั่งในช่วงของไฟล์ที่เฉพาะเจาะจงให้บอกว่า 18 ถึง 31

จนถึงตอนนี้ฉันได้ใช้วิธีดังต่อไปนี้

สามข้อโต้แย้ง

command file1[8-9].txt file2[0-9].txt file3[0-1].txt

ทีนี้สมมติว่าฉันต้องการเลขทุกตัว

ห่วง

for i in `jot - 18 31 2`; do echo file${i}.txt; done | xargs command

ดูเหมือนว่าจะเป็นการวนซ้ำที่เชื่อถือได้มากขึ้น (การเว้นวรรคทำงาน)

for i in `jot - 18 31 2`; do echo "\"file${i}.txt\" "; done | xargs command

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

command `filerange file 18 31`

มีวิธีหรือคำแนะนำที่ดีกว่าในการทำสิ่งนี้อย่างมีประสิทธิภาพหรือไม่?

superuserผมต้องขออภัยล่วงหน้าหากฉันพลาดคำถามเดียวกันนี้ตอบที่อื่นในเว็บหรือบน


ฉันอัพเดตคำถามของฉันเพื่อรวมโซลูชันโดยใช้forลูปที่อนุญาตให้มีช่องว่างในชื่อไฟล์โดยใช้ xargs ดูเหมือนว่าจะทำงานถ้าคุณไม่มีทุบตี 4 หากคุณมีทุบตี 4 แล้วใช้การขยายรั้งแน่นอน! ดูคำตอบที่เลือก ปลั๊กไร้ยางอายเพื่ออัปเกรดทุบตีเสือดาวหิมะ
milkypostman

คำตอบ:


25

ลองสิ่งนี้:

for file in file{18..31}.txt

มันเป็นที่รู้จักในฐานะ "ลำดับนิพจน์" และเป็นส่วนหนึ่งของคุณลักษณะการขยายรั้งของ Bash มันทำงานได้ใน Bash 3 และ 4

คุณลักษณะการเพิ่มขึ้นนั้นใหม่สำหรับ Bash 4 คุณอาจมี Bash 3.x

ใน Bash 4 คุณสามารถทำได้:

$ for i in {1..6..2}; do echo $i; done
1
3
5

แต่ใน Bash 3 คุณต้องทำสิ่งนี้เพื่อให้ได้ผลลัพธ์เดียวกัน:

$ for ((i=1; i<=6; i+=2)); do echo $i; done

รูปแบบเดียวกันที่เพิ่มขึ้นโดยหนึ่ง:

$ for ((i=1; i<=6; i++)); do echo $i; done

ตัวเลขใด ๆ สามารถเป็นตัวแปรหรือนิพจน์ได้ อย่างไรก็ตามในการแสดงออกตามลำดับตัวเลขจะต้องมีค่าคงที่

นี่คือตัวอย่างการใช้แบบฟอร์มนั้นในไฟล์ของคุณ:

for ((i=18; i<=31; i++))
do
    echo "file${i}.txt"
done

คุณสมบัติใหม่ของการแสดงออกต่อเนื่องใน Bash 4 คือความสามารถในการรวมศูนย์นำหน้า สิ่งนี้มีประโยชน์หากคุณต้องการสร้าง (และใช้) ไฟล์หมายเลขที่สามารถเรียงลำดับได้อย่างถูกต้อง

ใน Bash 4:

touch file{001..010}.txt

จะสร้างไฟล์ชื่อ "file001.txt" ถึง "file010.txt" ชื่อของพวกเขาจะเรียงตามลำดับที่คาดหวัง หากไม่มีศูนย์นำหน้า "file10.txt" จะเรียงลำดับก่อน "file1.txt"

เพื่อทำงานกับไฟล์คุณสามารถใช้ไวยากรณ์ศูนย์นำหน้า:

for file in file{001..010}.txt; do echo "$file"; done

ใน Bash 3 หากคุณต้องการเลขศูนย์นำหน้าคุณต้องเพิ่มคุณค่าด้วยตัวคุณเอง:

for i in {1..10}
do
    printf -v i '%03d' $i 
    echo "file${i}.txt"
done

printfคำสั่งจะย่อหน้าค่าของฉันกับศูนย์ชั้นนำเพื่อให้ความกว้างเป็น 3 ตัวอย่างเช่น ( "4" กลายเป็น "004")

แก้ไข:

รองรับช่องว่างในชื่อไฟล์เป็นเรื่องง่าย:

$ touch "space name "{008..018..3}" more spaces"
$ ls -l sp*
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces
$ for f in "space name "{008..018..3}" more spaces"; do mv "$f" "${f}.txt"; done
$ ls -l sp*
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces.txt

ขอขอบคุณ! ฉันไม่รู้ว่าสิ่งนี้เป็นชีวิตของฉันทั้งชีวิต สิ่งหนึ่งที่ฉันไม่สามารถทำงานได้แม้ว่าจะเพิ่มขึ้นดูเหมือนจะไม่ทำงานในทุบตีรุ่น OSX เช่นฉันไม่สามารถ{1..10..2}ทำงานใน OSX ทุบตีได้
milkypostman

มันเป็นสาเหตุให้ Snow Leopard (ด้วยเหตุผลบางอย่าง) กำลังใช้ bash 3.1 นี่เป็นปัญหาซอฟต์แวร์
milkypostman

@milkypostman: คุณลักษณะการเพิ่มและเลขศูนย์นำหน้า {01..10}ยังใหม่สำหรับ Bash 4 คุณอาจมี Bash 3.x หากคุณต้องการคุณสมบัติการเพิ่มหรือเพื่อใช้ตัวแปรสำหรับขอบเขตของช่วงให้ใช้แบบฟอร์มนี้: for ((i=1; i<=10; i+=2}(หรือi++สำหรับการเพิ่มขึ้นทีละรายการ) ตัวเลขใด ๆ สามารถเป็นตัวแปรหรือนิพจน์ได้ จากนั้นเมื่อต้องการใช้ค่าภายในforลูป: echo "file${i}.txt". In Bash 3, if you need leading zeros, inside the for loop do: printf -vi '% 03d' $ i` ซึ่งจะเติมค่าของiด้วยศูนย์นำหน้าดังนั้นความกว้างคือ 3 ตัวอย่างเช่น ("4" กลายเป็น "004")
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

เดนนิสมีวิธีใดบ้างที่คุณจะอัปเดตโซลูชันของคุณเพื่อรวมฟอร์มสำรอง เป็นความคิดเห็นมันค่อนข้างงงกับสิ่งที่ฉันควรจะได้รับ
milkypostman

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