shell bash,如果数组中包含输入值,则中断循环

carvr3hs  于 2023-04-21  发布在  Shell
关注(0)|答案(3)|浏览(126)

我想检查用户输入值是否存在于数组中,然后停止检查输入。

var=( one two three )
while true; do
  read -p "Choose value:   " val
  for i in "${var[@]}";do
    [ "$i" = "$val" ] && exit 0;
  done
done

echo SUCCESS

脚本将退出,但我希望脚本继续并打印SUCCESS。
我尝试了break指令,但while循环只是继续,并没有中断。

wkftcu5l

wkftcu5l1#

在break语句中使用level,如下所示:

var=( one two three )
while true; do
  read -p "Choose value:   " val
  for i in "${var[@]}";do
    [ "$i" = "$val" ] && break 2;
  done
done
echo SUCCESS

它将中断外部循环(当处于级别2时)。

kyks70gy

kyks70gy2#

避免嵌套循环,需要从@Renaud Pacalet使用 * 关联 * 数组方法,另一种方法是格式化数组并使用[[...]]而不是[...],类似于:

  • 使用 extglob 功能:
#!/usr/bin/env bash

var=( one two three )
pattern=$(IFS='|'; printf '@(%s)' "${var[*]}")

while read -rp "Choose value:  " val; do
  [[ "$val" = $pattern ]] && {
    printf "SUCCESS\n" && break
  }
done
  • bashv 4.1开始,默认情况下,[[ ... ]]extglob功能/支持是打开的,任何较低版本都需要shopt -s extglob来启用它。
  • 使用=~运算符的正则表达式:
#!/usr/bin/env bash

var=( one two three )
pattern=$(IFS='|'; printf '%s' "${var[*]}")

while read -rp "Choose value:   " val; do
  [[ "$val" =~ $pattern ]] && {
    printf "SUCCESS\n" && break
  }
done
  • 测试的右侧不需要被引用,否则它将被视为文字而不是glob或regex。
cygmwpex

cygmwpex3#

你应该把exit 0替换为break 2(也就是说,中断两个循环级别)。另一个选择是打印成功消息并退出:

var=( one two three )
while true; do
  read -p "Choose value:   " val
  for i in "${var[@]}";do
    [ "$i" = "$val" ] && echo "SUCCESS" && exit 0;
  done
done

最后,如果你的bash支持它,一个以你的值作为键的关联数组会简化一点,只需要一个循环级别:

declare -A var=( ["one"]= ["two"]= ["three"]= )
while true; do
  read -p "Choose value:   " val
  [[ -v var["$val"] ]] && break
done

echo "SUCCESS"

相关问题