我试图在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,而我希望它失败。


当前回答

如何

echo $list | grep -w -q $x

您可以检查输出或$?上面的线来做决定。

Grep -w检查整个单词模式。添加-q可以防止列表回显。

其他回答

这几乎是你最初的提议,但几乎是一行。不像其他有效答案那么复杂,也不那么依赖于bash版本(可以使用旧的bash)。

OK=0 ; MP_FLAVOURS="vanilla lemon hazelnut straciatella"
for FLAV in $MP_FLAVOURS ; do [ $FLAV == $FLAVOR ] && { OK=1 ; break; } ; done
[ $OK -eq 0 ] && { echo "$FLAVOR not a valid value ($MP_FLAVOURS)" ; exit 1 ; }

我想我的提案在篇幅和风格上都还可以改进。

如果不是太长;你可以像这样用逻辑或比较把它们串在相等之间。

if [ $ITEM == "item1" -o $ITEM == "item2" -o $ITEM == "item3" ]; then
    echo In the list
fi 

我遇到过这个问题,虽然上面的问题很难看,但它比其他广义解决方案更明显。

在我看来,最简单的解决方案是在原始字符串前加上一个空格,并使用[[]]检查正则表达式。

haystack='foo bar'
needle='bar'

if [[ " $haystack " =~ .*\ $needle\ .* ]]; then
    ...
fi

对于包含needle作为子字符串的值,这将不会是假阳性,例如用haystack foo barbaz。

(这个概念是从JQuery的hasClass()-Method中偷来的)

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

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

如果将列表固定在脚本中,我最喜欢以下几个:

validate() {
    grep -F -q -x "$1" <<EOF
item 1
item 2
item 3
EOF
}

然后使用验证“$x”来测试是否允许使用$x。

如果你想要一行代码,并且不关心项目名称中的空格,你可以使用这个(注意-w而不是-x):

validate() { echo "11 22 33" | grep -F -q -w "$1"; }

注:

这是POSIX sh兼容的。 Validate不接受子字符串(如果需要,可以删除grep的-x选项)。 Validate将其参数解释为固定字符串,而不是常规字符串 表达式(如果需要,可以删除grep的-F选项)。

演示函数的示例代码:

for x in "item 1" "item2" "item 3" "3" "*"; do
    echo -n "'$x' is "
    validate "$x" && echo "valid" || echo "invalid"
done