bash 脚本中的正则表达式(for 循环)

发布于 2024-09-24 04:13:53 字数 247 浏览 6 评论 0原文

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

I want to parse the arguments given to a shell script by using a for-loop. Now, assuming I have 3 arguments, something like
for i in $1 $2 $3
should do the job, but I cannot predict the number of arguments, so I wanted use an RegEx for the range and $# as the number of the last argument. I don't know how to use these RegEx' in a for-loop, I tried something like
for i in $[1-$#]
which doesn't work. The loop only runs 1 time and 1-$# is being calculated, not used as a RegEx.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绝對不後悔。 2024-10-01 04:13:53

基本

如果您不指定 in 子句,默认情况下,for 循环将循环遍历命令行参数:

for arg; do
    echo "$arg"
done

如果您想明确,您可以获取所有参数为 "$@"。上面的循环相当于:

for arg in "$@"; do
    echo "$arg"
done

从 bash 手册页:

特殊参数

$@ — 扩展为位置参数,从 1 开始。当膨胀发生在
双引号,每个参数扩展为一个单独的单词。也就是说,"$@" 相当于"$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 标志接受一个参数,因此在 getopt 调用中将其指定为 a:alpha:,并且在其大小写末尾有一个 shift 2

Basic

A for loop by default will loop over the command-line arguments if you don't specify the in clause:

for arg; do
    echo "$arg"
done

If you want to be explicit you can get all of the arguments as "$@". The above loop is equivalent to:

for arg in "$@"; do
    echo "$arg"
done

From the bash man page:

Special Parameters

$@ — Expands to the positional parameters, starting from one. When the expansion occurs within
double quotes, each parameter expands to a separate word. That is, "$@" is equivalent to "$1" "$2" .... If the double-quoted expansion occurs within a word, the expansion of the first
parameter is joined with the beginning part of the original word, and the expansion of the
last parameter is joined with the last part of the original word. When there are no positional parameters, "$@" and $@ expand to nothing (i.e., they are removed).

Advanced

For heavy-duty argument processing, getopt + shift is the way to go. getopt will pre-process the command-line to give the user some flexibility in how arguments are specified. For example, it will expand -xzf into -x -z -f. It adds a -- argument after all the flags which separates flags from file names; this lets you do run cat -- -my-file to display the contents of -my-file without barfing on the leading dash.

Try this boilerplate code on for size:

#!/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

Notice that each option has a short a long equivalent, e.g. -a and --alpha. The -a flag takes an argument so it's specified as a: and alpha: in the getopt call, and has a shift 2 at the end of its case.

离笑几人歌 2024-10-01 04:13:53

另一种迭代参数的方法更接近您正在努力的方向,类似于:

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

但 John Kugelman 展示的 for arg 语法是迄今为止更可取的。然而,有时数组切片很有用。此外,在这个版本中,与约翰的版本一样,参数数组保持不变。使用 shift 会丢弃其元素。

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

Another way to iterate over the arguments which is closer to what you were working toward would be something like:

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

but the for arg syntax that John Kugelman showed is by far preferable. There are, however, times when array slicing is useful. Also, in this version, as in John's, the argument array is left intact. Using shift discards its elements.

You should note that what you were trying to do with square brackets is not a regular expression at all.

我建议做其他事情:

while [ -n "$1" ] ; do
  # Do something with $1
  shift
  # Now whatever was in $2 is now in $1
done

shift 关键字将 $2 的内容移动到 $1,将 $3 移动到 $2,等等。 pp.

让我们说一下参数:

a b c d

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 现在引用 shift 之前索引 2 处的元素。我希望你明白我想说的话。

I suggest doing something else instead:

while [ -n "$1" ] ; do
  # Do something with $1
  shift
  # Now whatever was in $2 is now in $1
done

The shift keyword moves the content of $2 into $1, $3 into $2, etc. pp.

Let's say the arguments where:

a b c d

After a shift, the arguments are now:

b c d

With the while loop, you can thus parse an arbitrary number of arguments and can even do things like:

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

Imagine the arguments as being an array and $n being indexes into that array. shift removes the first element, so the index 1 now references the element that was at index 2 prior to shift. I hope you understand what I want to say.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文