我想通过使用 for 循环来解析提供给 shell 脚本的参数。现在,假设我有 3 个参数,
for i in $1 $2 $3
应该可以完成这项工作,但我无法预测参数的数量,所以我想使用 RegEx 作为范围,并使用 $# 作为最后一个参数的数量。我不知道如何在 for 循环中使用这些 RegEx',我尝试了一些
for i in $[1-$#]
不起作用的方法。该循环仅运行 1 次,并且正在计算 1-$#,而不是用作 RegEx。
3 回答
基本的
如果您不指定子句for
,默认情况下循环将遍历命令行参数:in
for arg; do
echo "$arg"
done
如果您想明确,您可以将所有参数作为"$@"
. 上面的循环等价于:
for arg in "$@"; do
echo "$arg"
done
从 bash 手册页:
特殊参数
$@
— 从一开始扩展到位置参数。当扩展出现在双引号内时,每个参数都扩展为一个单独的单词。即,"$@"
等价于"$1" "$2" ...
。如果双引号扩展出现在一个单词中,则第一个参数的扩展与原始单词的开头部分连接,最后一个参数的扩展与原始单词的最后部分连接。当没有位置参数时,"$@"
扩展$@
为空(即,它们被删除)。
先进的
对于繁重的参数处理,getopt
+shift
是要走的路。getopt
将预处理命令行,以便用户在如何指定参数方面具有一定的灵活性。例如,它将扩展-xzf
为-x -z -f
. --
它在将标志与文件名分开的所有标志之后添加一个参数;这使您可以运行cat -- -my-file
以显示内容,-my-file
而不会在前导破折号上吐槽。
试试这个样板代码的大小:
#!/bin/bash
eval set -- "$(getopt -o a:bch -l alpha:,bravo,charlie,help -n "$0" -- "$@")"
while [[ $1 != -- ]]; do
case "$1" in
-a|--alpha)
echo "--alpha $2"
shift 2
;;
-b|--bravo)
echo "--bravo"
shift
;;
-c|--charlie)
echo "--charlie"
shift
;;
-h|--help)
echo "Usage: $0 [-a ARG] [-b] [-c]" >&2
exit 1
;;
esac
done
shift
请注意,每个选项都有一个短的等价物,例如-a
和--alpha
。该-a
标志接受一个参数,因此它在调用中指定为a:
and ,并在其 case 的末尾有 a 。alpha:
getopt
shift 2
另一种迭代更接近您正在努力的参数的方法是:
for ((i=1; i<=$#; i++))
do
echo "${@:i:1}"
done
但for arg
John Kugelman 展示的语法要好得多。但是,有时数组切片很有用。此外,在这个版本中,就像在约翰的版本中一样,参数数组保持不变。使用shift
丢弃它的元素。
您应该注意,您尝试使用方括号执行的操作根本不是正则表达式。
我建议做其他事情:
while [ -n "$1" ] ; do
# Do something with $1
shift
# Now whatever was in $2 is now in $1
done
这shift
内容移动到 $1,将 $3 移动到 $2,依此类推。
让我们说一下论点:
a b c d
在 a 之后shift
,参数现在是:
b c d
使用 while 循环,您可以解析任意数量的参数,甚至可以执行以下操作:
while [ -n "$1" ] ; do
if [ "$1" = "-f" ] ; then
shift
if [ -n "$1" ] ; then
myfile="$1"
else
echo "-f needs an additional argument"
end
fi
shift
done
将参数想象为一个数组,而 $n 是该数组的索引。shift
删除第一个元素,因此索引 1 现在引用 . 之前位于索引 2 的元素shift
。我希望你明白我想说什么。