我想检查一个字符串是否以“节点”开始,例如。“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

我怎样才能正确地做呢?


当前回答

高级Bash脚本编写指南中的这段代码说:

# The == comparison operator behaves differently within a double-brackets
# test than within single brackets.

[[ $a == z* ]]   # True if $a starts with a "z" (wildcard matching).
[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).

所以你几乎是对的;你需要双括号,而不是单括号。


关于你的第二个问题,你可以这样写:

HOST=user1
if  [[ $HOST == user1 ]] || [[ $HOST == node* ]] ;
then
    echo yes1
fi

HOST=node001
if [[ $HOST == user1 ]] || [[ $HOST == node* ]] ;
then
    echo yes2
fi

会产生回声

yes1
yes2

Bash的if语法很难习惯(IMO)。

其他回答

grep

忘记性能,这是POSIX,看起来比大小写解决方案更好:

mystr="abcd"
if printf '%s' "$mystr" | grep -Eq '^ab'; then
  echo matches
fi

解释:

printf '%s'以防止printf扩展反斜杠转义:Bash printf字面逐字串 grep -q防止匹配回显到stdout:如何使用Bash检查文件是否包含特定字符串 grep -E启用扩展正则表达式,这是^ . grep所需要的

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

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

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

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

我更喜欢已经发布的其他方法,但有些人喜欢使用:

case "$HOST" in 
    user1|node*) 
            echo "yes";;
        *)
            echo "no";;
esac

编辑:

我已经在上面的案例陈述中添加了你的替补

在你编辑过的版本中,括号太多了。它应该是这样的:

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

因为#在Bash中有意义,所以我采用了以下解决方案。

此外,我更喜欢用“”来填充字符串,以克服空格等。

A="#sdfs"
if [[ "$A" == "#"* ]];then
    echo "Skip comment line"
fi

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

表达式

$HOST == node*

也可以写成

$HOST == "node"*

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