Có một chương trình unix tiêu chuẩn trả về một phạm vi số


22

Tôi đang học kịch bản shell từ một cuốn sách giáo khoa lỗi thời và có vẻ như tôi thực sự hữu ích khi có một chương trình chỉ trả về một chuỗi các số được phân cách bằng khoảng trắng giống như

$ range 10 20
10 11 12 13 14 15 16 17 18 19 20

Sau đó, nếu bạn đang thực hiện một kịch bản shell, bạn có thể có

for i in `range 10 20`; do some stuff with numbers in that range;done

Có một thứ như vậy tồn tại, hoặc tôi cần phải tự viết nó?


Khi bạn nói "unix", bạn thực sự có nghĩa là Linux? Hay bạn thực sự quan tâm đến tính di động đối với các hệ thống khác (Solaris, BSD, ...)?
glenn jackman

2
s / phạm vi / seq - thay thế rangebằng seqtrong ví dụ của bạn. dấu phân cách mặc định là dòng mới, để có khoảng trắng:seq -s " " 10 20
n611x007

@naxa Cho dù đó là không gian hay dòng mới không quan trọng trong forvòng lặp hay thậm chí bất kỳ lệnh chung nào phân tách đối số, trừ khi bạn đặt IFS khác nhau.
slhck

1
Câu hỏi này sẽ xác định "chương trình unix tiêu chuẩn" nghĩa là gì đối với OP.
David Rivers

1
Như @DavidRivers đã nhận xét, bạn nên nêu tiêu đề và câu hỏi bạn tập trung vào các bản phân phối Linux. Câu trả lời bạn chấp nhận cho thấy một công cụ KHÔNG phải là chương trình Unix tiêu chuẩn. Một số Unix đang thiếu seqvì nó không được chỉ định bởi POSIX.
jlliagre

Câu trả lời:


79

seq là một phần của coreutils.

for i in $( seq 1 2 11 ) ; do echo $i ; done

Đầu ra:

1
3
5
7
9
11

Nếu bạn chỉ cung cấp 2 đối số cho seq, số gia là 1:

$ seq 4 9
4
5
6
7
8
9

2
sedcũng có các tùy chọn đẹp như -sđặt dải phân cách hoặc -wđủ điều kiện chiều rộng. Và bạn có thể cung cấp một mức tăng: seq -w -s ", " 0 5 20kết quả trong 00, 05, 10, 15, 20 .
scai

2
@scai ý bạn là seqgì?
Carlos Campderrós

@ CarlosCampderrós Tất nhiên, thật không may, tôi không thể chỉnh sửa nhận xét của mình nữa.
scai

3
seq 10 20cũng có thể là một ví dụ đơn giản đáng để thêm vào;)
Der Hochstapler

@scai thật tuyệt vời, tôi đã học được một điều mới ngày hôm nay :) thành thật mà nói, tôi nghĩ bạn nên thêm nó như một câu trả lời riêng biệt, chi tiết hơn!
Tim Groeneveld

33

Bash sẽ đủ?

for i in {10..20}; do echo $i; done

Bạn có thể làm rất nhiều thứ với mở rộng cú đúp . Bash 4 cũng hỗ trợ phạm vi đệm, ví dụ {01..20}.

Lưu ý rằng Bash không được coi là di động và không phải là tiện ích Unix tiêu chuẩn. Mặc dù bạn có thể cho rằng nó được cài đặt một cách an toàn trên hầu hết các Linux hiện đại, nhưng đừng sử dụng điều này trong một tập lệnh mà bạn dự định chạy trên tất cả các loại máy giống Unix.


13
@Maksim: Mặc dù tôi cũng thích mở rộng niềng răng này, nhưng cũng có một công cụ Un * x điển hình (làm rất ít, nhưng làm tốt điều đó) cho điều đó : seq. Việc sử dụng là như trong ví dụ của bạn : seq -s " " 10 20. Các -stham số là cần thiết, bởi vì theo mặc định các giá trị được phân cách bằng \n.
mpy

Vâng, Bash không phải là "tiêu chuẩn" tùy thuộc vào mức độ nghiêm ngặt của bạn diễn giải điều đó. Tôi chỉ thấy dễ dàng hơn để xử lý và nó không yêu cầu thêm một cuộc gọi.
slhck

1
@mpy, lưu ý rằng seqlà một tiện ích GNU, và do đó không phải là một "chương trình unix tiêu chuẩn"
glenn jackman

5
@glennjackman Theo developer.apple.com/library/Mac/documentation/Darwin/Reference/... ... "Lệnh seq đầu tiên xuất hiện trong kế hoạch 9 từ Bell Labs. lệnh Một seq xuất hiện trong NetBSD 3.0, và chuyển đến FreeBSD 9.0 Lệnh này được dựa trên lệnh cùng tên trong Kế hoạch 9 từ Bell Labs và các tiện ích lõi GNU. Lệnh GNU seq xuất hiện lần đầu tiên trong bản phát hành tiện ích shell 1.13. "
200_success

Cũng lưu ý rằng bạn có thể làm for i in {001..010}; ... ; donevà nó sẽ không đệm số đến 3 chữ số.
VoliverseDream

9

Nếu bạn muốn một cái gì đó hoàn toàn di động (nghĩa là không dựa vào các phần mở rộng bash cụ thể hoặc các lệnh không được chỉ định bởi POSIX)

awk 'BEGIN {for(i=10;i<=20;i++) printf "%d ",i; print}'

1
Bạn không cần phải thêm /dev/nullhoặc thêm < /dev/nullvào đó?
Scott

1
@ Hủy bỏ Không, điều này là không cần thiết. Tiêu chuẩn POSIX ( pubs.opengroup.org/onlinepub/9699919799/utilities/ mẹo ) chỉ định:If the awk program contains no actions and no patterns, but is otherwise a valid awk program, standard input and any file operands shall not be read and awk shall exit with a return status of zero.
jlliagre

6

Trước 10.7 không có seqtrên Mac OS X, nhưng jot, do di sản BSD.

jot -- print sequential or random data

...

HISTORY
    The jot utility first appeared in 4.2BSD

Thí dụ:

$ jot - 1 3
1
2
3


2

Bạn có thể sử dụng seqhoặc nếu bạn không có điều đó, bạn có thể tự viết nó:

#!/bin/bash
[ $# -ge 1 ] || { echo "Usage: seq Number [ Number ]" 1>&2 ; exit 1; }
[ $# -eq 1 ] && { [ $1 -gt 1 ] && ./seq $(($1 - 1)) ; echo $1 ; }
[ $# -eq 2 ] && { [ $(($2 - $1)) -gt 0 ] && ./seq $1 $(($2 - 1)) ; echo $2 ; }

Sử dụng:

$ ./seq 3
1
2
3

Hoặc là:

$ ./seq 3 7
3
4
5
6
7

1

Để hoàn thiện ở đây, một cái gì đó sẽ hoạt động với một số biến thể cũ hơn của Unix (miễn là chúng đã được cài đặt perl). Không thực sự thanh lịch.

for I in $(perl -e 'print join("\n", 1..10)'); do something with $I; done
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.