Bagaimana cara menampilkan angka dalam urutan terbalik menggunakan seq (1)?


36

Saya telah mengulangi angka dalam berbagai urutan. Saya dapat menampilkannya dalam urutan yang meningkat, bahkan dengan langkah-langkah seperti:

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

Saya juga dapat menampilkannya dalam urutan terbalik, baik secara terus menerus maupun langkah bijak.

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

Tidak ada output untuk perintah di atas.

Detail shell saya:

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

Biarkan saya tahu bagaimana saya bisa menampilkan angka dalam urutan menurun?


10
Untuk pembaca masa depan, seqadalah alat yang sama sekali tidak standar dan tidak ada jaminan bahwa dua implementasi akan sama. Jika Anda perlu menulis lingkaran yang mundur ke belakang angka dalam bash, gunakan for ((i=$max;i>=0;i--)) …atau sejenisnya.
kojiro

Jawaban:


50

gunakan kenaikan negatif

seq -s, 10 -2 1
10,8,6,4,2

20

Secara umum, Anda tidak ingin menggunakan seq, itu tidak portabel (bahkan di antara lingkungan Linux standar). Jika Anda menggunakan ksh, zsh, atau bash4 +, Anda dapat menggunakan brace expansion:

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

1
Itu singkat dan cepat, tetapi saya menggunakan versi bash yang lebih lama.
mtk

20
Jawaban yang manis, tetapi ada beberapa ironi ketika Anda menunjukkan seqtidak standar dan kemudian menggunakan ekspansi brace bash-4-only. ;)
kojiro

@kojiro - Tidak ada argumen untuk jujur ​​;-) Perhatian utama saya bukan pada apakah perintah itu ada (yang mungkin atau mungkin tidak masalah tergantung pada apakah skrip sedang didistribusikan / etc), tetapi apakah perintah dijalankan seperti yang diharapkan oleh penulis. Ekspansi brace bash4 hampir memiliki jaminan (jika berfungsi, ini berfungsi seperti yang Anda harapkan), sedangkan seqtidak.
Chris Down

1
Kenapa tidak portabel? Apakah Anda memiliki sumber atau bukti? Saya tertarik.
Benoit Duffez

15

Cara lain dalam bash, ksh, atau zsh murni:

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

Cara POSIX murni:

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

1
forEkspresi kedua harus menjadi ujian dan yang ketiga adalah langkah.
manatwork

7

Sekarang, yang POSIX standar:

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

(Menariknya, dengan mawk(dan pada tingkat lebih rendah)gawk juga) jauh lebih cepat daripada GNU sequntuk i = 10000000bukannya i = 10)

Atau

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

(hanya akan lebih efisien dengan sejumlah kecil iterasi, terutama dengan bash)

Atau

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

(yang akan mendukung angka dengan ukuran berapa pun, tetapi perhatikan bahwa melewati sejumlah digit tertentu (angka lebih besar dari 10 70 di POSIX lokal setidaknya), garis akan dibungkus dengan garis miring terbalik)


1
Di GNU bc, Anda dapat menghindari garis pembungkus dengan pengaturan BC_LINE_LENGTH=0di lingkungan. Tidak ada keberuntungan pada implementasi lain.
Gilles 'SANGAT berhenti menjadi jahat'

1
Mengapa menggunakan argumen posisi alih-alih berputar-putar s=$s,$iatau memanggil echo -n/ echo \c/ printf?
Gilles 'SANGAT berhenti menjadi jahat'

2

Anda dapat membalik urutan menggunakan tac(cat terbalik). Bahkan jika seqharus berperilaku berbeda pada berbagai sistem, saya pikir yang berikut ini harus se portable mungkin:

$ 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
$

2

Coba dengan:

   seq [OPTION]... FIRST INCREMENT LAST

Contoh:

$ seq 10 -1 1

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.