Làm cách nào để hiển thị số theo thứ tự ngược bằng seq (1)?


36

Tôi đã lặp đi lặp lại qua các số theo thứ tự khác nhau. Tôi có thể hiển thị chúng theo thứ tự tăng dần, thậm chí với các bước như:

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

Tôi cũng có thể hiển thị chúng theo thứ tự ngược lại, không liên tục cũng không phải là bước khôn ngoan.

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

Không có đầu ra cho các lệnh trên.

Chi tiết vỏ của tôi:

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

Hãy cho tôi biết làm thế nào tôi có thể hiển thị các số theo thứ tự giảm dần?


10
Đối với độc giả trong tương lai, seqlà một công cụ hoàn toàn phi tiêu chuẩn và không có gì đảm bảo rằng bất kỳ hai triển khai nào cũng sẽ giống nhau. Nếu bạn cần viết một vòng lặp lặp lại các số trong bash, hãy sử dụng for ((i=$max;i>=0;i--)) …hoặc tương tự.
kojiro

Câu trả lời:



20

Nói chung, bạn không muốn sử dụng seq, nó không khả dụng (ngay cả trong các môi trường Linux tiêu chuẩn). Nếu bạn đang sử dụng ksh, zsh hoặc bash4 +, bạn có thể sử dụng mở rộng dấu ngoặc:

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

1
Đó là ngắn và nhanh chóng, nhưng tôi đang ở phiên bản bash cũ.
mtk

20
Câu trả lời ngọt ngào, nhưng có một số điều trớ trêu khi bạn chỉ ra seqlà không chuẩn và sau đó sử dụng mở rộng niềng răng chỉ bash-4. ;)
kojiro

@kojiro - Không có đối số để thành thật ;-) Mối quan tâm chính của tôi không phải là vấn đề có tồn tại hay không (điều đó có thể hay không phụ thuộc vào việc tập lệnh có được phân phối / v.v.) hay không, nhưng liệu lệnh có thực thi như mong đợi không tác giả. mở rộng cú đúp của bash4 gần như đã được đảm bảo (nếu nó hoạt động, nó hoạt động như bạn mong đợi), trong khi seqkhông.
Chris Xuống

1
Tại sao nó không di động? Bạn có nguồn hoặc bằng chứng? Tôi quan tâm.
Benoit Duffez

15

Một cách khác trong bash thuần, ksh hoặc zsh:

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

Một cách sh POSIX thuần túy:

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

1
forBiểu thức thứ hai nên là bài kiểm tra và bước thứ ba.
manatwork

7

Bây giờ, những cái POSIX tiêu chuẩn:

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

(thú vị, với mawk(và đến một mức độ thấp hơn gawklà tốt) nhanh hơn rất nhiều so với GNU seqcho i = 10000000thay vì i = 10)

Hoặc là

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

(sẽ chỉ hiệu quả hơn với số lần lặp nhỏ, đặc biệt là với bash)

Hoặc là

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

(sẽ hỗ trợ các số có kích thước bất kỳ, nhưng lưu ý rằng vượt qua một số chữ số nhất định ( ít nhất là số lớn hơn 10 70 trong ngôn ngữ POSIX), các dòng sẽ được bọc bằng dấu gạch chéo ngược)


1
Trong GNU bc, bạn có thể tránh việc ngắt dòng bằng cách đặt BC_LINE_LENGTH=0trong môi trường. Không có may mắn như vậy trên các triển khai khác.
Gilles 'SO- ngừng trở nên xấu xa'

1
Tại sao sử dụng các đối số vị trí thay vì lặp xung quanh s=$s,$ihoặc gọi echo -n/ echo \c/ printf?
Gilles 'SO- ngừng trở nên xấu xa'

2

Bạn có thể đảo ngược thứ tự bằng cách sử dụng tac(con mèo ngược lại). Ngay cả khi seqnên hành xử khác nhau trên các hệ thống khác nhau, tôi nghĩ rằng những điều sau đây nên càng dễ mang theo:

$ 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

Hãy thử với:

   seq [OPTION]... FIRST INCREMENT LAST

Thí dụ:

$ seq 10 -1 1

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.