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


当前回答

假设TARGET变量只能是“二项式”或“回归”,那么如下所示:

# Check for modeling types known to this script
if [ $( echo "${TARGET}" | egrep -c "^(binomial|regression)$" ) -eq 0 ]; then
    echo "This scoring program can only handle 'binomial' and 'regression' methods now." >&2
    usage
fi

您可以通过使用|(管道)字符分隔更多字符串到列表中。

使用egrep的优点是可以轻松地添加大小写不敏感(-i),或者使用正则表达式检查更复杂的场景。

其他回答

[[ $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

如何

echo $list | grep -w -q $x

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

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

另一种受公认回答启发的解决方案,但使用了相反的逻辑:

MODE="${1}"

echo "<${MODE}>"
[[ "${MODE}" =~ ^(preview|live|both)$ ]] && echo "OK" || echo "Uh?"

这里,输入($MODE)必须是正则表达式中的一个选项('preview', 'live',或'both'),而不是将整个选项列表匹配到用户输入。当然,您不会期望正则表达式发生变化。

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

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

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

假设TARGET变量只能是“二项式”或“回归”,那么如下所示:

# Check for modeling types known to this script
if [ $( echo "${TARGET}" | egrep -c "^(binomial|regression)$" ) -eq 0 ]; then
    echo "This scoring program can only handle 'binomial' and 'regression' methods now." >&2
    usage
fi

您可以通过使用|(管道)字符分隔更多字符串到列表中。

使用egrep的优点是可以轻松地添加大小写不敏感(-i),或者使用正则表达式检查更复杂的场景。