วิธีการแสดงตัวเลขในลำดับย้อนกลับโดยใช้ seq (1)


36

ฉันทำซ้ำตัวเลขตามลำดับต่างๆ ฉันสามารถแสดงผลตามลำดับที่เพิ่มขึ้นแม้จะมีขั้นตอนดังนี้:

$ seq --separator="," 1 10
1,2,3,4,5,6,7,8,9,10
$ seq --separator="," 1 2 10
1,3,5,7,9

ฉันยังสามารถแสดงพวกเขาในลำดับกลับกันไม่ต่อเนื่องหรือขั้นตอนที่ชาญฉลาด

$ seq --separator="," 10 1   
$ seq --separator="," 10 2 1

ไม่มีเอาต์พุตสำหรับคำสั่งด้านบน

รายละเอียดเปลือกของฉัน:

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

แจ้งให้ฉันทราบว่าฉันจะสามารถแสดงตัวเลขตามลำดับจากมากไปน้อยได้อย่างไร


10
สำหรับผู้อ่านในอนาคตseqเป็นเครื่องมือที่ไม่เป็นมาตรฐานอย่างสมบูรณ์และไม่มีการรับประกันว่าการใช้งานสองแบบจะเหมือนกัน หากคุณต้องการเขียนลูปที่วนซ้ำย้อนหลังเป็นตัวเลขใน bash ให้ใช้for ((i=$max;i>=0;i--)) …หรือกด Like
kojiro

คำตอบ:



20

โดยทั่วไปคุณไม่ต้องการใช้seqมันไม่สามารถพกพาได้ (แม้จะอยู่ในสภาพแวดล้อม Linux มาตรฐาน) หากคุณใช้ ksh, zsh หรือ bash4 + คุณสามารถใช้การขยายรั้ง:

echo {10..1..2} | tr " " ,
10,8,6,4,2

1
สั้นและเร็ว แต่ฉันใช้เวอร์ชั่นทุบตีรุ่นเก่า
mtk

20
คำตอบหวาน ๆ แต่มีประชดเมื่อคุณชี้ให้เห็นseqว่าไม่เป็นมาตรฐานแล้วใช้การขยายรั้ง bash-4 เท่านั้น ;)
kojiro

@kojiro - ไม่มีข้อโต้แย้งใด ๆ ที่จะซื่อสัตย์ ;-) ข้อกังวลหลักของฉันไม่ใช่หนึ่งในคำสั่งที่มีอยู่ (ซึ่งอาจหรืออาจไม่สำคัญขึ้นอยู่กับว่าสคริปต์จะถูกกระจาย / etc) แต่คำสั่งดำเนินการตามที่คาดไว้หรือไม่ ผู้เขียน. การขยายตัวรั้ง bash4 เกือบมีที่รับประกัน (ถ้าทำงานก็ทำงานตามที่คุณคาด) ในขณะที่seqไม่ได้
Chris Down

1
ทำไมมันไม่สามารถพกพาได้? คุณมีแหล่งที่มาหรือบทพิสูจน์หรือไม่? ฉันสนใจ.
เบอนัวต์ดัฟเฟซ

15

อีกวิธีในการทุบตีบริสุทธิ์ ksh หรือ zsh:

for ((i=10;i>0;i-=2)) ; do echo -n "$i," ; done

วิธี POSIX บริสุทธิ์:

i=10
while [ "$i" -gt 2 ]; do printf "$i,"; i=$((i-2)); done
echo "$i"

1
forนิพจน์ที่สองของควรเป็นการทดสอบและขั้นตอนที่สาม
จัดการ

7

ตอนนี้ POSIX มาตรฐาน:

awk 'BEGIN{for (i = 10; i > 0; i -= 2) print i}' | paste -sd , -

(ที่น่าสนใจที่มีmawk(และในระดับน้อยgawkเช่นกัน) มากเร็วกว่า GNU seqสำหรับi = 10000000แทนi = 10)

หรือ

i=10; set --
while [ "$i" -gt 0 ]; do
  set -- "$@" "$i"
  i=$(($i - 2))
done
IFS=,
echo "$*"

(จะมีประสิทธิภาพมากขึ้นเมื่อมีการวนซ้ำจำนวนน้อยโดยเฉพาะกับbash)

หรือ

echo 'for(i=10;i>0;i-=2) i' | bc | paste -sd , -

(ซึ่งจะรองรับตัวเลขขนาดใดก็ได้ แต่โปรดทราบว่าผ่านจำนวนตัวเลขที่แน่นอน (ตัวเลขที่มากกว่า 10 70ในโลแคล POSIX อย่างน้อย) บรรทัดจะถูกล้อมด้วยแบ็กสแลช)


1
ใน GNU bc คุณสามารถหลีกเลี่ยงการตัดบรรทัดด้วยการตั้งค่าBC_LINE_LENGTH=0ในสภาพแวดล้อม ไม่มีโชคเช่นนี้กับการใช้งานอื่น ๆ
Gilles 'หยุดความชั่วร้าย'

1
ใช้ข้อโต้แย้งตำแหน่งทำไมมากกว่าวนรอบs=$s,$iหรือโทรecho -n/ echo \c/ printf?
Gilles 'ดังนั้น - หยุดความชั่วร้าย'

2

คุณสามารถกลับรายการโดยใช้tac(cat ย้อนกลับ) แม้ว่าseqควรจะทำงานแตกต่างกันในระบบต่าง ๆ ฉันคิดว่าสิ่งต่อไปนี้ควรพกพาได้มากที่สุด:

$ seq 1 10 | tr '\012' ',' | sed 's/,$//'; echo
1,2,3,4,5,6,7,8,9,10
$ seq 1 10 | tac | tr '\012' ',' | sed 's/,$//'; echo
10,9,8,7,6,5,4,3,2,1
$

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