มีโปรแกรมยูนิกซ์มาตรฐานที่คืนค่าตัวเลขหรือไม่


22

ฉันเรียนรู้การเขียนสคริปต์เชลล์จากตำราเรียนที่ล้าสมัยและฉันคิดว่ามันจะเป็นประโยชน์อย่างยิ่งที่จะมีโปรแกรมที่เพิ่งคืนค่าตัวเลขที่คั่นด้วยช่องว่างเช่น

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

จากนั้นถ้าคุณทำสคริปต์เชลล์คุณสามารถมี

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

สิ่งนั้นมีอยู่จริงหรือฉันต้องเขียนเอง?


เมื่อคุณพูดว่า "unix" คุณหมายถึง Linux จริง ๆ หรือ หรือคุณสนใจพกพาไปยังระบบอื่น ๆ (Solaris, BSD, ... ) หรือไม่
เกล็นแจ็

2
s / range / seq - แทนที่rangeด้วยseqในตัวอย่างของคุณ ตัวคั่นเริ่มต้นคือบรรทัดใหม่เพื่อให้มีช่องว่าง:seq -s " " 10 20
n611x007

@naxa ไม่ว่าจะเป็นช่องว่างหรือการขึ้นบรรทัดใหม่ไม่สำคัญในforลูป - หรือแม้แต่คำสั่งทั่วไปที่แยกอาร์กิวเมนต์ - ยกเว้นว่าคุณได้ตั้งค่า IFS ต่างกัน
slhck

1
คำถามนี้ควรกำหนดว่า "โปรแกรมยูนิกซ์มาตรฐาน" หมายถึง OP อย่างไร
David Rivers

1
ในฐานะที่เป็น @DavidRivers แสดงความคิดเห็นแล้วคุณควรระบุในชื่อและคำถามที่คุณมุ่งเน้นไปที่การกระจาย Linux คำตอบที่คุณตอบรับนั้นเป็นเครื่องมือที่ไม่ใช่โปรแกรม Unix มาตรฐาน Unix หลายตัวขาดseqเนื่องจากไม่ได้ระบุไว้โดย POSIX
jlliagre

คำตอบ:


79

seq เป็นส่วนหนึ่งของ coreutils

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

เอาท์พุท:

1
3
5
7
9
11

หากคุณให้ข้อโต้แย้งเพียง 2 ข้อseqการเพิ่มขึ้นคือ 1:

$ seq 4 9
4
5
6
7
8
9

2
sedยังมีตัวเลือกที่ดีเช่น-sการตั้งค่าตัวคั่นหรือ-wเพื่อปรับความกว้าง และคุณสามารถให้เพิ่มขึ้น: seq -w -s ", " 0 5 20ผลใน 00, 05, 10, 15, 20
scai

2
@ ลายคุณหมายถึงseqอะไร
Carlos Campderrós

@ CarlosCampderrósแน่นอนน่าเสียดายที่ฉันไม่สามารถแก้ไขความคิดเห็นของฉันได้อีก
scai

3
seq 10 20อาจเป็นตัวอย่างง่ายๆที่ควรค่าแก่การเพิ่ม;)
Der Hochstapler

@scai ที่ยอดเยี่ยมฉันเรียนรู้สิ่งใหม่วันนี้ :) พูดตามตรงฉันคิดว่าคุณควรจะเพิ่มคำตอบที่แยกต่างหากและละเอียดกว่านี้ออก!
Tim Groeneveld

33

Bash จะเพียงพอหรือไม่

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

คุณสามารถทำสิ่งต่างๆมากมายที่มีการขยายตัวรั้ง ทุบตี 4 {01..20}นอกจากนี้ยังสนับสนุนช่วงเบาะเช่น

โปรดทราบว่า Bash นั้นไม่ถือเป็นแบบพกพาไม่ใช่ยูทิลิตี้ Unix มาตรฐาน แม้ว่าคุณสามารถสันนิษฐานได้อย่างปลอดภัยว่าติดตั้งบน Linux ที่ทันสมัยส่วนใหญ่อย่าใช้สิ่งนี้ในสคริปต์ที่คุณวางแผนที่จะใช้กับเครื่อง Unix ทุกประเภท


13
@Maksim: ถึงแม้ว่าผมจะยังชอบการขยายตัวรั้งนี้ยังมีทั่วไป Un * x เครื่องมือ (ทำน้อยมาก แต่ทำอย่างนั้นด้วย) seqว่า: seq -s " " 10 20การใช้งานจะเป็นในตัวอย่างของคุณ: พารามิเตอร์เป็นสิ่งจำเป็นเพราะโดยค่าเริ่มต้นค่าจะถูกคั่นด้วย-s \n
mpy

ใช่ Bash ไม่ใช่ "มาตรฐาน" ขึ้นอยู่กับว่าคุณตีความเข้มงวดมากแค่ไหน ฉันเพิ่งพบว่าจัดการได้ง่ายกว่าและไม่ต้องการการโทรเพิ่ม
slhck

1
@mpy ทราบว่าseqเป็นสาธารณูปโภค GNU และดังนั้นจึงไม่ได้เป็น "มาตรฐานโปรแกรมยูนิกซ์"
เกล็น Jackman

5
@glennjackman อ้างอิงจากdeveloper.apple.com/library/Mac/documentation/Darwin/Reference/ ...... ... "คำสั่ง seq ปรากฏครั้งแรกใน Plan 9 จาก Bell Labs คำสั่ง seq ปรากฏใน NetBSD 3.0 และส่งไปยัง FreeBSD 9.0 คำสั่งนี้ยึดตามคำสั่งของชื่อเดียวกันใน Plan 9 จาก Bell Labs และยูทิลิตีหลักของ GNU คำสั่ง GNU seq ปรากฏขึ้นครั้งแรกในการวางจำหน่าย 1.13 shell Utilities "
200_success

โปรดทราบว่าคุณสามารถทำได้for i in {001..010}; ... ; doneและจะทำให้ตัวเลขเป็นศูนย์เป็นตัวเลข 3 หลัก
VolatileDream

9

หากคุณต้องการบางสิ่งบางอย่างพกพาอย่างเข้มงวด (เช่นที่ไม่พึ่งพาส่วนขยายทุบตีเฉพาะหรือคำสั่งที่ไม่ได้ระบุโดย POSIX)

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

1
คุณไม่ต้องการที่จะเพิ่ม/dev/nullหรือ< /dev/nullว่า?
สกอตต์

1
@Scott ไม่สิ่งนี้ไม่จำเป็น มาตรฐาน POSIX ( pubs.opengroup.org/onlinepubs/9699919799/utilities/ … ) ระบุ: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

ก่อนหน้า 10.7 นั้นไม่มีseqใน Mac OS X แต่jotเนื่องมาจากมรดก BSD

jot -- print sequential or random data

...

HISTORY
    The jot utility first appeared in 4.2BSD

ตัวอย่าง:

$ jot - 1 3
1
2
3


2

คุณสามารถใช้seqหรือถ้าคุณไม่มีคุณสามารถเขียนเอง:

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

การใช้งาน:

$ ./seq 3
1
2
3

หรือ:

$ ./seq 3 7
3
4
5
6
7

1

เพื่อความสมบูรณ์ที่นี่บางสิ่งบางอย่างที่จะทำงานร่วมกับ Unix รุ่นเก่าบางรุ่น (ตราบใดที่มีการติดตั้ง Perl) ไม่หรูหราจริงๆ

for I in $(perl -e 'print join("\n", 1..10)'); do something with $I; done
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.