我试图在bash中编写一个脚本,检查用户输入的有效性。 我想将输入(变量x)匹配到一个有效值列表。

我现在想到的是:

for item in $list
do
    if [ "$x" == "$item" ]; then
        echo "In the list"
        exit
    fi
done

我的问题是,如果有更简单的方法, 对于大多数编程语言,类似list.contains(x)。

列表是:

list="11 22 33"

我的代码将只对这些值回显消息,因为list被视为数组而不是字符串, 所有的字符串操作都将验证1,而我希望它失败。


当前回答

有一种更简单的方法来检查string是否在列表中:

if [[ $my_str = @(str1|str2|str3) ]]; then
    echo "string found"
fi

其他回答

Matvey是对的,但你应该引用$x,并考虑任何类型的“空格”(例如新行)

[[ $list =~ (^|[[:space:]])"$x"($|[[:space:]]) ]] && echo 'yes' || echo 'no' 

所以,即。

# list_include_item "10 11 12" "2"
function list_include_item {
  local list="$1"
  local item="$2"
  if [[ $list =~ (^|[[:space:]])"$item"($|[[:space:]]) ]] ; then
    # yes, list include item
    result=0
  else
    result=1
  fi
  return $result
}

然后结束

`list_include_item "10 11 12" "12"`  && echo "yes" || echo "no"

or

if `list_include_item "10 11 12" "1"` ; then
  echo "yes"
else 
  echo "no"
fi

注意,在变量的情况下必须使用"":

`list_include_item "$my_list" "$my_item"`  && echo "yes" || echo "no"

考虑利用关联数组的键。我认为这优于正则表达式/模式匹配和循环,尽管我还没有对其进行分析。

declare -A list=( [one]=1 [two]=two [three]='any non-empty value' )
for value in one two three four
do
    echo -n "$value is "
    # a missing key expands to the null string, 
    # and we've set each interesting key to a non-empty value
    [[ -z "${list[$value]}" ]] && echo -n '*not* '
    echo "a member of ( ${!list[*]} )"
done

输出:

1是(1,2,3)的成员 2是(1,2,3)的一个元素 3是(1,2,3)的一个元素 4不是(1,2,3)的成员

如果你使用双括号,你也可以在case语句外使用(*通配符):

string='My string';

if [[ $string == *My* ]]
then
echo "It's there!";
fi

下面的脚本实现了一个列表的包含函数。

    function contains {
      local target=$1
      shift
    
      printf '%s\n' "$@" | grep -x -q "$target"
      out=$?
      (( out = 1 - out ))
      return $out
    }

如果将一个基于空白的字符串转换为一个列表并使用它,它似乎可以按以下方式解决。


    list="11 22 33"
    IFS=" " read -ra parsed_list <<< "$list"
    
    # parsed_list would be ("11" "22" "33")
    
    contains "11" "${parsed_list[@]}"
    echo $?  # 1
    
    contains "22" "${parsed_list[@]}"
    echo $?  # 1
    
    contains "1" "${parsed_list[@]}"
    echo $? # 0
    
    contains "11 22" "${parsed_list[@]}"
    echo $? # 0
[[ $list =~ (^|[[:space:]])$x($|[[:space:]]) ]] && echo 'yes' || echo 'no'

或者创建一个函数:

contains() {
    [[ $1 =~ (^|[[:space:]])$2($|[[:space:]]) ]] && exit(0) || exit(1)
}

使用它:

contains aList anItem
echo $? # 0: match, 1: failed