删除shell脚本(POSIX)中的最后一个参数
我目前正在开发一种旨在编译成POSIX外壳语言的语言,我想介绍一种删除shell脚本(POSIX)中的最后一个参数,shell,sh,posix,Shell,Sh,Posix,我目前正在开发一种旨在编译成POSIX外壳语言的语言,我想介绍一种pop特性。就像使用“shift”删除传递给函数的第一个参数一样: f(){ 转移 printf'%s'$*“ } f 1 2 3#=>2 3 我想要一些代码,在下面介绍时可以删除最后一个参数 g(){ #流行音乐 printf'%s'$*“ } G23#=>12 我知道在()中详细介绍的数组方法,但是我想要一种至少能在以下shell中工作的可移植的方法:ash、dash、ksh(Unix)、bash和zsh。我还想要一些速度
pop
特性。就像使用“shift”删除传递给函数的第一个参数一样:
f(){
转移
printf'%s'$*“
}
f 1 2 3#=>2 3
我想要一些代码,在下面介绍时可以删除最后一个参数
g(){
#流行音乐
printf'%s'$*“
}
G23#=>12
我知道在()中详细介绍的数组方法,但是我想要一种至少能在以下shell中工作的可移植的方法:ash、dash、ksh(Unix)、bash和zsh。我还想要一些速度合理的东西;打开外部进程/子shell的东西对于小参数计数来说太重了,我想如果你有一个创造性的解决方案,我不介意看到它(它们仍然可以用作大参数计数的后备方案)。与那些数组方法一样快的方法是理想的。这是我目前的答案:
pop(){
本地n=$($1-${2:-1}))
如果[-n“$ZSH_版本”-o-n“$BASH_版本”];则
POP_EXPR='set--“${@:1:'$n'}”
elif[$n-ge 500];然后
POP|EXPR=“set--$(seq-s”“1$n|sed's/[0-9]\+/“${\0}”/g”)”
其他的
本地索引=0
局部参数=“”
而[$index-lt$n];则
索引=$((索引+1))
arguments=“$arguments\”\${$index}”
完成
POP_EXPR=“set--$arguments”
fi
}
请注意,local
不是POSIX,但是由于所有主要的sh
shell都支持它(特别是我在问题中要求的那些shell),并且没有它可能会导致严重的bug,因此我决定将它包含在这个引导函数中。但这里有一个完全兼容的POSIX版本,带有模糊参数,以减少出现bug的可能性:
pop(){
__pop_n=$($1-${2:-1}))
如果[-n“$ZSH_版本”-o-n“$BASH_版本”];则
POP_EXPR='set--“${@:1:'$\u POP_n'}”
elif[$\u pop\n-ge 500];然后
POP\u EXPR=“set--$(seq-s”“1$\u POP\u n | sed's/[0-9]\+/“${\0}”/g”)
其他的
__pop_指数=0
__pop_arguments=“”
而[$\u pop\u index-lt$\u pop\u n];则
__pop_指数=$((pop_指数+1))
__pop\u arguments=“$\uU pop\u arguments\”\${$\uU pop\u index}”
完成
POP_EXPR=“设置--$\uu POP_参数”
fi
}
用法
pop1(){
流行音乐$#
评估“$POP_EXPR”
回显“$@”
}
pop2(){
流行音乐$#2
评估“$POP_EXPR”
回显“$@”
}
pop1 a b c#=>a b
pop1$(seq 1 1000)#=>1。。999
pop2$(seq 1 1000)#=>1。。998
下一个
使用POP创建POP_EXPR
变量后,可以使用以下命令
函数将其更改为省略其他参数:
pop_next(){
如果[-n“$BASH_版本”-o-n“$ZSH_版本”];则
本地np=“${POP_EXPR##*:}”
np=“${np%\}*}”
POP_EXPR=“${POP_EXPR%:*}:$((np==0?0:np-1))}”
返回
fi
POP\U EXPR=“${POP\U EXPR%\”*}”
}
pop_next
是比posix shell中的pop
简单得多的操作(尽管它是
比zsh和bash上的pop
稍微复杂一些)
它是这样使用的:
main(){
流行音乐$#
下一个
评估“$POP_EXPR”
}
主1 2 3#=>1
POP_EXPR和变量范围
请注意,如果您不打算在之后立即使用eval“$POP_EXPR”
pop
和pop\u next
,如果您对某些函数调用的作用域不小心
在这两个操作之间,可能会更改POP_EXPR
变量并弄乱事情
向上的为了避免这种情况,只需在每个函数的开头添加local POP_EXPR
如果可用,则使用pop
f(){
本地流行音乐
流行音乐$#
g 1 2
评估“$POP_EXPR”
printf“%s”f=$*“
}
g(){
本地流行音乐
流行音乐$#
评估“$POP_EXPR”
printf“%s”,g=$*“
}
f a b c#=>g=1,f=a b
popgen.sh
这个特殊的函数对于我来说已经足够好了,但是我确实创建了一个
脚本生成进一步优化的函数
在不使用外部工具的情况下提高性能的方法之一是
要认识到有几个小字符串串联是很慢的,那么
它们分批使用使功能大大加快。调用脚本
popgen.sh-gN1、N2、N3
创建一个处理操作的pop函数
根据参数计数,以N1、N2或N3批为单位。剧本也
包含其他技巧,举例说明如下:
$sh popgen\
>-g 10100 \#成批连接字符串\
>-w\#覆盖当前文件\
>-x9 \#硬编码前9个参数计数的结果\
>-t1000 \#从参数计数1000开始,使用外部工具\
>-p posix \#要添加到函数名的前缀(带下划线)\
>要添加到函数名的-s“”后缀(带下划线)\
>-c \#使用命令popsh代替seq/sed作为外部工具\
>-@\#在zsh和bash上,使用子数组方法(运行时检查)\
>-+\\使用bash/zsh扩展(从-@中删除运行时检查)\
>-nl \#不要使用“本地”\
>-f \#使用“函数”语法\
>-o pop.sh#输出文件
可以使用popgen.sh-t500-g1-@
生成与上述函数等效的函数。
在包含popgen.sh
的要点中,您将找到一个popsh.c
文件,该文件可以
编译并用作默认shell的专用、更快的替代方案
外部工具,它将被生成的任何函数使用
popgen.sh-c…
如果shell可以通过popsh
访问它。
或者,您可以创建名为popsh
的任何函数或工具并使用
取而代之的是它
基准
基准功能:
我用于基准测试的脚本可以在以下要点中找到:
基准函数可在以下行中找到:
脚本可以这样使用:
$sh popbench.sh\
>-s dash \#基准使用的shell,可以是das