Apakah ada program unix standar yang mengembalikan sejumlah angka

22

Saya belajar shell scripting dari buku teks yang sudah ketinggalan zaman, dan bagi saya sepertinya akan sangat berguna untuk memiliki program yang hanya mengembalikan serangkaian angka yang dibatasi oleh spasi seperti

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

Kemudian, jika Anda melakukan skrip shell Anda dapat memiliki

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

apakah hal semacam itu ada, atau apakah saya perlu menulisnya sendiri?

MYV
sumber
ketika Anda mengatakan "unix", apakah Anda benar-benar bermaksud Linux? Atau apakah Anda benar-benar tertarik pada portabilitas ke sistem lain (Solaris, BSD, ...)?
glenn jackman
2
s / range / seq - ganti rangedengan seqdalam contoh Anda. pemisah default adalah baris baru, memiliki spasi:seq -s " " 10 20
n611x007
@naxa Apakah spasi atau baris baru tidak masalah di forloop — atau bahkan perintah umum apa pun yang memecah argumen — kecuali Anda telah mengatur IFS secara berbeda.
slhck
1
Pertanyaan ini harus mendefinisikan apa arti "program unix standar" untuk OP.
David Rivers
1
Karena @DavidRivers sudah berkomentar, Anda harus menyatakan judulnya dan pertanyaannya adalah fokus Anda pada distribusi Linux. Jawaban yang Anda terima menyarankan alat yang BUKAN program Unix standar. Beberapa Unix kurang seqkarena tidak ditentukan oleh POSIX.
jlliagre

Jawaban:

79

seq adalah bagian dari coreutils.

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

Keluaran:

1
3
5
7
9
11

Jika Anda hanya memberikan 2 argumen seq, kenaikannya adalah 1:

$ seq 4 9
4
5
6
7
8
9
choroba
sumber
2
sedjuga memiliki opsi bagus -suntuk mengatur pemisah atau -wuntuk memenuhi syarat lebarnya. Dan Anda dapat memberikan peningkatan: seq -w -s ", " 0 5 20hasil dalam 00, 05, 10, 15, 20 .
scai
2
@ bisa Anda maksudkan seq?
Carlos Campderrós
@ CarlosCampderrós Tentu saja, sayangnya saya tidak dapat mengedit komentar saya lagi.
scai
3
seq 10 20mungkin juga menjadi contoh sederhana yang layak ditambahkan;)
Der Hochstapler
@scai itu luar biasa, saya belajar sesuatu yang baru hari ini :) jujur ​​saja, saya pikir Anda harus menambahkan itu sebagai jawaban yang terpisah dan lebih detail!
Tim Groeneveld
33

Apakah Bash sudah cukup?

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

Anda dapat melakukan banyak hal dengan ekspansi brace . Bash 4 juga mendukung rentang empuk, mis {01..20}.

Perhatikan bahwa Bash tidak dianggap portabel, dan bukan utilitas Unix standar. Meskipun Anda dapat dengan aman berasumsi bahwa itu diinstal pada sebagian besar Linux modern, jangan gunakan ini dalam skrip yang Anda rencanakan untuk dijalankan pada semua jenis mesin seperti Unix.

slhck
sumber
13
@Maksim: Meskipun saya juga lebih suka ekspansi brace ini, ada juga yang khas Un * x tool (melakukan sangat sedikit, tetapi melakukannya dengan baik) untuk itu: seq. Pemakaian ini seperti dalam contoh Anda: seq -s " " 10 20. The -sparameter ini diperlukan, karena secara default nilai-nilai dipisahkan oleh \n.
mpy
Ya, Bash bukan "standar" tergantung pada seberapa ketat Anda menafsirkannya. Saya merasa lebih mudah ditangani dan tidak memerlukan panggilan tambahan.
slhck
1
@ mpy, perhatikan itu seqadalah utilitas GNU, dan karena itu bukan "program unix standar"
glenn jackman
5
@glennjackman Menurut developer.apple.com/library/Mac/documentation/Darwin/Reference/ ... ... "Perintah seq pertama kali muncul di Plan 9 dari Bell Labs. Perintah seq muncul di NetBSD 3.0, dan dipindahkan ke FreeBSD 9.0 Perintah ini didasarkan pada perintah dengan nama yang sama di Plan 9 dari Bell Labs dan utilitas inti GNU. Perintah seq GNU pertama kali muncul di rilis utilitas shell 1,13. "
200_sukses
Juga perhatikan bahwa Anda dapat melakukannya for i in {001..010}; ... ; donedan itu akan nol pad angka menjadi 3 digit.
VolatileDream
9

Jika Anda menginginkan sesuatu yang sepenuhnya portabel (yaitu yang tidak bergantung pada ekstensi bash tertentu atau perintah yang tidak ditentukan oleh POSIX)

awk 'BEGIN {for(i=10;i<=20;i++) printf "%d ",i; print}'
Jlliagre
sumber
1
Apakah Anda tidak perlu menambahkan /dev/nullatau < /dev/nullitu?
Scott
1
@ Esc Tidak, ini tidak perlu. Standar POSIX ( pubs.opengroup.org/onlinepubs/9699919799/utilities/… ) menetapkan: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

Sebelum 10.7 tidak ada seqpada Mac OS X, tetapi jot, karena warisan BSD.

jot -- print sequential or random data

...

HISTORY
    The jot utility first appeared in 4.2BSD

Contoh:

$ jot - 1 3
1
2
3
miku
sumber
2

Gunakan satu forlingkaran

for ((i = 10; i <= 20; ++i)); do
    printf '%d\n' "$i"
done
pengguna27076
sumber
2

Anda dapat menggunakan seq, atau jika Anda tidak memiliki itu, Anda dapat menulis sendiri:

#!/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 ; }

Pemakaian:

$ ./seq 3
1
2
3

Atau:

$ ./seq 3 7
3
4
5
6
7
StackedCrooked
sumber
1

Demi kelengkapan di sini sesuatu yang akan bekerja dengan beberapa varian Unix yang lebih lama (selama mereka telah menginstal perl). Tidak terlalu elegan.

for I in $(perl -e 'print join("\n", 1..10)'); do something with $I; done
reto
sumber