zsh 命令行处理 - 将最后的参数与之前的参数分开

zsh command line processing - separating the last arguments from the previous ones

我正在编写一个 zsh 脚本,它使用可变数量的参数调用,例如

 scriptname a b c d filename

在脚本中,我想首先遍历参数(除了最后一个)并处理它们,最后对处理后的数据和最后一个参数(文件名)做一些事情。

我成功了,但对我的解决方案并不完全满意。这是我想出的(其中 processapply 是一些与我的问题无关的其他脚本):

#!/bin/zsh
set -u
x=""
filename=$@[-1]
# Process initial arguments
for ((i=1; i<$#; i++))
do
  x+=$(process ${@[$i]}) 
done
apply $x $filename

我觉得计数循环太麻烦了。如果 filename 是第一个参数,我会做一个 shift 然后可以在保存文件名后简单地遍历参数。但是我想将文件名保留为最后一个参数(为了与其他工具保持一致)。

有没有关于如何在不计算循环的情况下巧妙地编写此代码的想法?

如果可以的话,您可以从原始列表中切掉最后一个参数并将它们保存到一个数组中

args=("${@:1:$# -1}")
for arg in "${args[@]}"; do          # iterate over all, except the last
  printf '%s\n' "$arg"
done

使用数组作为占位符是可选的,因为您可以直接遍历参数切片,即 for arg in "${@:1:$# -1}"; do。该语法甚至在 bash 中也可用。


正如 所指出的,您可以使用 zsh 特定的语法,如

for arg in $@[1,-2]; do
  printf '%s\n' "$arg"
done