如何检查值是否在列表中?

时间:2014-06-04 09:22:49

标签: bash list

我有一个带有来自命令行参数的变量的脚本。我想检查其值是否为devbetaprod之一。我有一个以下代码片段:

#!/usr/bin/env bash

ENV_NAME=$1

echo "env name = $ENV_NAME"
ENVIRONMENTS=('dev','beta','prod')
if [[ $ENVIRONMENTS =~ $ENV_NAME ]]; then
    echo 'correct'
    exit
else
    echo 'incorrect'
    exit
fi

当我运行我的脚本时,无论我传递哪些参数:./script.sh beta./script.sh./script.sh whatever,我总是会回复correct。我的剧本有什么问题?

4 个答案:

答案 0 :(得分:2)

for i in ${ENVIRONMENTS[@]}; do
  if [[ $i = $ENV_NAME ]]; then
    echo "correct"
    exit
  fi
done

echo 'incorrect'
exit

答案 1 :(得分:2)

使用bash re:

ENV_NAME=dev
ENVIRONMENTS="dev|beta|prod"
[[ $ENV_NAME =~ ^($ENVIRONMENTS)$ ]] && echo ${BASH_REMATCH[1]}
dev

答案 2 :(得分:2)

每个人都有一个很好的建议,但还有另一种方式。它比使用正则表达式更有效,并且可能比使用循环更有效,尤其是在具有更多值时。唯一的问题是这需要Bash 4.0或更新版本。

declare -A ENVIRONMENTS=([dev]=. [beta]=. [prod]=.)
if [[ -n ${ENVIRONMENTS["$ENV_NAME"]} ]]; then
...

答案 3 :(得分:0)

将其置于函数

我喜欢隐藏丑陋的实现细节,特别是在涉及bash时。

function catPipe()      # concatenate all arguments with a pipe character
{
  local IFS='|'
  echo "$*"
}

function matchList()
{
  local needle="$1"
  shift
  local stack=$(catPipe "$@")
  [[ "$needle" =~ ^($stack)$ ]]
}

如果你不喜欢有子贝壳,请使用:

function matchList()
{
  local needle="$1"
  shift
  IFS='|' eval 'local stack="$*"'
  [[ "$needle" =~ ^($stack)$ ]]
}

受konsolebox'解决方案的启发,我使用^($ var)$语法来避免部分匹配。首先它看起来像这样:

function matchList()
{
  local needle="$1"
  shift
  local stack="$@"
  [[ ${stack[@]} =~ "$needle" ]]  # would allow partial machtes like 'eta'
}

可以使用字符串,数组或单个项目调用该函数:

variants='dev beta prod'
varArray=(dev beta prod)

matchList prop $variants && echo 'prop: match!'
matchList beta $variants && echo 'beta: match!'
matchList beta ${varArray[@]} && echo 'beta: match!'
matchList eta alpha beta gamma && echo 'eta: match!'
# Output:
beta: match!
beta: match!

或者原始示例:

matchList $ENV_NAME ${ENVIRONMENTS[@]} && echo 'correct'

案例(部分解决方案)

旁注:我试图用案例提出解决方案,因为它自然符合要求。 它有效,但我无法弄清楚是否/如何在声明中使用环境。

ENV_NAME='beta'
ENVIRONMENTS='dev|beta|prod'
case $ENV_NAME in (dev|beta|prod) echo 'correct' ;; (*) echo 'incorrect' ;; esac