我想检查一个字符串是否以“节点”开始,例如。“node001”。类似的

if [ $HOST == user* ]
  then
  echo yes
fi

我怎样才能正确地做呢?


我进一步需要组合表达式来检查HOST是否为“user1”或以“node”开头

if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ];
then
echo yes
fi

> > > -bash: [: too many arguments

我怎样才能正确地做呢?


当前回答

保持简单

word="appel"

if [[ $word = a* ]]
then
  echo "Starts with a"
else
  echo "No match"
fi

其他回答

你可以选择你想要检查的字符串部分:

if [ "${HOST:0:4}" = user ]

对于你接下来的问题,你可以使用OR:

if [[ "$HOST" == user1 || "$HOST" == node* ]]

如果您正在使用最新版本的Bash (v3+),我建议使用Bash正则表达式比较运算符=~,例如,

if [[ "$HOST" =~ ^user.* ]]; then
    echo "yes"
fi

要在正则表达式中匹配这个或那个,使用|,例如,

if [[ "$HOST" =~ ^user.*|^host1 ]]; then
    echo "yes"
fi

注意——这是“正确的”正则表达式语法。

User *表示使用和零次或多次出现r,因此使用和userrrr将匹配。 用户。*表示用户和零或多次出现任何字符,因此user1, userX将匹配。 ^用户。*表示匹配模式用户。*在$HOST的开头。

如果您不熟悉正则表达式语法,请尝试参考此资源。

请注意,Bash =~操作符仅在右侧为unquote时进行正则表达式匹配。如果你在右边引用,“模式的任何部分都可以被引用,以迫使它作为字符串进行匹配。”即使在进行参数展开时,也不应该在右边引用。

@OP,对于你的两个问题,你可以使用case/esac:

string="node001"
case "$string" in
  node*) echo "found";;
  * ) echo "no node";;
esac

第二个问题

case "$HOST" in
 node*) echo "ok";;
 user) echo "ok";;
esac

case "$HOST" in
 node*|user) echo "ok";;
esac

或者Bash 4.0

case "$HOST" in
 user) ;&
 node*) echo "ok";;
esac

在Mark Rushakoff的最高级别答案中添加了更多的语法细节。

表达式

$HOST == node*

也可以写成

$HOST == "node"*

效果是一样的。只要确保通配符在引用的文本之外。如果通配符在引号内,它将按字面解释(即不是通配符)。

虽然我发现这里的大多数答案都是正确的,但其中许多都包含不必要的bashism。POSIX参数展开为您提供所需的一切:

[ "${host#user}" != "${host}" ]

and

[ "${host#node}" != "${host}" ]

${var#expr}从${var}中剥离匹配expr的最小前缀并返回。因此,如果${host}不以用户(节点)开头,${host#user} (${host#node})与${host}相同。

Expr允许fnmatch()通配符,因此${host#node??朋友也能工作。