替代 GNU seq(1) 的便携式 POSIX shell?

Eli*_*fox 11 posix portability seq

我注意到seq(1)除了 GNU 系统之外,您不能真正指望在任何系统上都可用。seq(1)用 POSIX(不是 bash)shell 编写的我可以随身携带的简单重新实现是什么?

编辑:请注意,我打算至少在各种 BSD、Solaris 和 Mac OS X 上使用它。

Sté*_*las 9

另一种方法awkbc

seq() (first=$1 incr=$2 last=$3
  echo "for (i = $first; i <= $last; i+=$incr) i" | bc -l
)
Run Code Online (Sandbox Code Playgroud)

一个优点是您不受 CPU 双精度的大小/分辨率的限制:

$ seq '(2^200)' '(2^100)' '(2^200+2^102)'
1606938044258990275541962092341162602522202993782792835301376
1606938044258990275541962092342430253122431223184289538506752
1606938044258990275541962092343697903722659452585786241712128
1606938044258990275541962092344965554322887681987282944917504
1606938044258990275541962092346233204923115911388779648122880
Run Code Online (Sandbox Code Playgroud)

但是当数字太大时要注意换行:

$ seq '(2^500)' '(2^100)' '(2^500+2^101)'
32733906078961418700131896968275991522166420460430647894832913680961\
33796404674554883270092325904157150886684127560071009217256545885393\
053328527589376
32733906078961418700131896968275991522166420460430647894832913680961\
33796404674554883270092325904157150886684127560071010484907146113622\
454825230794752
32733906078961418700131896968275991522166420460430647894832913680961\
33796404674554883270092325904157150886684127560071011752557746341851\
856321934000128
Run Code Online (Sandbox Code Playgroud)


gro*_*mal 6

根据开放组POSIX awk 支持BEGIN,因此可以在awk

awk -v MYEND=6 'BEGIN { for(i=1;i<=MYEND;i++) print i }'
Run Code Online (Sandbox Code Playgroud)

哪里-v MYEND=6将代表赋值,如第一个参数中的seq. 换句话说,这也有效:

END=6
for i in `awk -v MYEND=$END 'BEGIN { for(i=1;i<=MYEND;i++) print i }'`; do
    echo $i
done
Run Code Online (Sandbox Code Playgroud)

或者甚至使用三个变量(开始、增量和结束):

S=2
I=2
E=12
for i in `awk -v MYS=$S -v MYI=$I -v MYE=$E 'BEGIN { for(i=MYS;i<=MYE;i+=MYI) print i }'`; do
    echo $i
done
Run Code Online (Sandbox Code Playgroud)

额外的Solaris注意:在 Solaris/usr/bin/awk兼容 POSIX,您需要在 Solaris 上使用nawk/usr/xpg4/bin/awk

在 Solaris 上,/usr/xpg4/bin如果您正在运行符合 POSIX 的脚本,您可能希望在 PATH 中尽早设置。

参考答案:

  • Solaris old-awk 确实有 BEGIN(还有 END);它缺少的是“开始加上没有中间自动退出”。您可以通过在 BEGIN 操作中说“退出”来解决此问题,或者通过重定向或文件操作数提供到达 EOF 的输入;`/dev/null` 很好,因为它总是存在并且总是空的。虽然_一般_ nawk 或 xpg4 更方便。 (2认同)

Kaj*_*nbo 5

while是 POSIX

i=1
while [ "$i" -ne 11 ]
do    
    echo $i
    i=$(( $i + 1 ))
done
Run Code Online (Sandbox Code Playgroud)

while便携式、多功能且经常未被充分利用。