4

我想通过使用 for 循环来解析提供给 shell 脚本的参数。现在,假设我有 3 个参数, for i in $1 $2 $3 应该可以完成这项工作,但我无法预测参数的数量,所以我想使用 RegEx 作为范围,并使用 $# 作为最后一个参数的数量。我不知道如何在 for 循环中使用这些 RegEx',我尝试了一些 for i in $[1-$#] 不起作用的方法。该循环仅运行 1 次,并且正在计算 1-$#,而不是用作 RegEx。

4

3 回答 3

7

基本的

如果您不指定子句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:getoptshift 2

于 2010-09-18T20:35:16.553 回答
1

另一种迭代更接近您正在努力的参数的方法是:

for ((i=1; i<=$#; i++))
do
    echo "${@:i:1}"
done

for argJohn Kugelman 展示的语法要好得多。但是,有时数组切片很有用。此外,在这个版本中,就像在约翰的版本中一样,参数数组保持不变。使用shift丢弃它的元素。

您应该注意,您尝试使用方括号执行的操作根本不是正则表达式。

于 2010-09-19T03:29:00.143 回答
0

我建议做其他事情:

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。我希望你明白我想说什么。

于 2010-09-18T20:37:00.660 回答