วิธีสร้างลำดับด้วยเลขศูนย์นำหน้าโดยใช้การขยายรั้ง


45

เมื่อฉันใช้สิ่งต่อไปนี้ฉันได้รับผลลัพธ์ตามที่คาดไว้:

$ echo {8..10}
8 9 10

ฉันจะใช้การขยายรั้งนี้ในวิธีที่ง่ายเพื่อให้ได้ผลลัพธ์ต่อไปนี้ได้อย่างไร

$ echo {8..10}
08 09 10

ตอนนี้ฉันสามารถใช้สิ่งนี้ได้seq(ไม่ลอง) แต่นั่นไม่ใช่สิ่งที่ฉันกำลังมองหา

ข้อมูลที่มีประโยชน์อาจเป็นได้ว่าฉันถูก จำกัด รุ่น bash นี้ (หากคุณมีzshวิธีแก้ไข แต่ไม่มีbashวิธีแก้ไขโปรดแชร์ด้วย)

$ bash -version
GNU bash, version 3.2.51(1)-release (x86_64-suse-linux-gnu)

คำแนะนำบางอย่างในการทุบตี 3 ฉันพบที่นี่: mywiki.wooledge.org/BashFAQ/018อย่างไรก็ตามวิธีการที่ระบุไว้ไม่สะดวก
แบร์นฮาร์ด

คำตอบ:


70

นำหน้าตัวเลขแรกด้วย a 0เพื่อบังคับให้แต่ละคำมีความกว้างเท่ากัน

$ echo {08..10}
08 09 10

จากส่วนหน้าคนทุบตีในการขยายรั้ง:

จำนวนเต็มที่ให้อาจนำหน้าด้วย 0 เพื่อบังคับให้แต่ละคำมีความกว้างเท่ากัน เมื่อ x หรือ y เริ่มต้นด้วยศูนย์เชลล์จะพยายามบังคับเงื่อนไขที่สร้างขึ้นทั้งหมดเพื่อให้มีจำนวนหลักเท่ากันโดยไม่มีการเติมเต็มศูนย์ในกรณีที่จำเป็น

นอกจากนี้โปรดทราบว่าคุณสามารถใช้seqกับ-wตัวเลือกเพื่อปรับความกว้างให้เท่ากันด้วยการเติมด้วยศูนย์นำ:

$ seq -w 8 10
08
09
10

$ seq -s " " -w 8 10
08 09 10

หากคุณต้องการการควบคุมที่มากขึ้นคุณสามารถระบุรูปแบบสไตล์ printf:

$ seq -s " " -f %02g 8 10
08 09 10

8
หลังจากเพิ่งค้นพบเกี่ยวกับการecho {08..10}แก้ปัญหาอย่างไรก็ตามมันถูกแนะนำสำหรับ bash รุ่น 4 ขึ้นไปเท่านั้น
Bernhard

นั่นทำให้ฉันอึดอัดเล็กน้อยที่ทุบตีทำเช่นนั้น สำหรับพวงของยูทิลิตี้ (ตัวอย่างperl) ศูนย์นำหน้าจะระบุหมายเลขฐานแปด ฉันคิดว่ามันเป็นไปไม่บ่อยครั้งที่คุณต้องการลำดับของตัวเลขฐานแปด ...
kurtm

5
มันควรจะตั้งข้อสังเกตว่าคุณยังสามารถนำหน้าตัวเลขเมื่อให้ไปแล้วseqกับ-wสวิทช์เช่นดังนั้น: seq -w 003ผลิตเลขที่ 001, 002 และ 003
SLM

@ เคิร์ตไม่ต้องกังวลกับเลขศูนย์นำหน้า นั่นอาจเจ็บเมื่อมีบางสิ่งพยายามแยกตัวเลข สิ่งนี้มีประโยชน์จริง ๆ คือการสร้างลำดับชื่อไฟล์foo_00001.someextensionที่บริบทการเรียงลำดับเกือบทั้งหมดให้การสั่งซื้อที่มีเหตุผล
Stéphane Gourichon

9

ถ้าคุณใช้ printf

printf "%.2d " {8..10} 

สิ่งนี้จะบังคับให้เป็น 2 ตัวอักษรและจะเพิ่ม 0 นำหน้าในกรณีที่คุณต้องการ 3 หลักคุณสามารถเปลี่ยนเป็น "% .3d"


ขอบคุณสำหรับคำตอบ. ฉันรู้printfวิธีแก้ปัญหา แต่ก็ไม่ได้ทำให้ง่ายขึ้นจริงๆ ฉันหวังว่าจะมีบางส่วนเคล็ดลับที่ซ่อนอยู่ที่จะทำงาน :)
เบอร์นาร์ด

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

7

ใช้ช่วงที่เริ่มต้นด้วยตัวเลขคงที่และตัดตัวเลขนั้นออก:

echo \ {108..110} | sed 's/ 1//g'

หรือไม่ใช้คำสั่งภายนอก:

a=({108..110}); echo "${a[@]#1}"

สำหรับใช้ในวง for:

for x in {108..110}; do
  x=${x#1}
  
done

แม้ว่าในกรณีนี้ a while loop จะชัดเจนขึ้นและทำงานใน POSIX เชลล์ใด ๆ :

x=8
while [ $x -le 10 ]; do
  n=$((100+x)); n=${n#1}
  
  x=$((x+1))
done

ฉันยอมรับคำตอบนี้เหนือคำตอบอื่น ๆ เพราะเป็นไปตามคำขอ Bash 3.x โดยเฉพาะอย่างยิ่งที่ฉันต้องการforห่วงอย่างไรก็ตาม
แบร์นฮาร์ด

6

ฉันมีโปสเตอร์ดั้งเดิม ( GNU bash, version 3.2.51(1)-release) เวอร์ชั่นทุบตีเหมือนกันและ{08..12}ไม่ทำงานสำหรับฉัน แต่สิ่งต่อไปนี้จะ:

for i in 0{8..9} {10..12}; do echo $i; done
08
09
10
11
12

มันน่าเบื่อกว่านี้นิดหน่อย แต่มันใช้งานได้กับเวอร์ชั่นทุบตี OP (และเวอร์ชั่นต่อมาฉันจะสมมุติ)


ผมไม่ได้คิดเกี่ยวกับการแก้ปัญหานี้ ( แต่ในกรณีของฉันที่จริงผมก็อยากไปที่หมายเลข 0001 1000 แต่หลักการทำงานของคุณแน่นอน.
เบอร์นาร์ด

1

สำหรับการอ้างอิงฉันคิดว่าความกว้างคงที่อัตโนมัติจะเกิดขึ้นกับ bash รุ่นล่าสุดเท่านั้น:

$ bash -version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

$ echo test{00..05}
test0 test1 test2 test3 test4 test5

-3
for i in $(seq -s " " -f %0${zeros}g $ini $fin); do ....;done

ศูนย์, ini และ fin เป็น vars, ดังนั้นมันง่าย, yo เขียนเฉพาะศูนย์ที่คุณพูดใน 'ศูนย์' สำหรับ ini ถึง fin โดยไม่มีปัญหา;)

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