比较Bash中的两个字符串


22

我的ifbash脚本中包含以下代码块:

if [ ${PACKAGENAME} -eq kakadu-v6_4-00902C ]; then
  echo "successfully entered if block!!"
fi

if即使$PACKAGENAME等于,脚本执行也不会进入我的程序段kakadu-v6_4-00902C。我究竟做错了什么?


9
-eq对于整数是正确的,您要测试字符串或正则表达式(===~):mywiki.wooledge.org/BashGuide/TestsAndConditionals
jasonwryan 2014年

谢谢,jasonwryan我将看一下这个资源!
DemiSheep 2014年

Answers:


31

-eq 是算术运算符,用于比较两个数字。

使用=(便携式/标准sh=~==替代。

也请使用引号,因为如果${PACKAGENAME}包含空格或通配符,则它将被拆分为多个参数,这将导致[看到比期望更多的参数。请参阅此处常见的bash陷阱列表。

if [ "${PACKAGENAME}" = 'kakadu-v6_4-00902C' ]; then
    echo "successfully entered if block!!"
fi

请参阅man bash,在(/)中搜索CONDITIONAL EXPRESSIONS


1
啊! 谢谢!有效!我显然是这个菜鸟。感谢您的帮助!
DemiSheep 2014年

2
您看过tldp.org/LDP/Bash-Beginners-Guide/html吗?这是一个非常不错的bash指南,它将帮助您进行示例和考试:)。
polym

1
谢谢,polym我来看看,感谢您的资源!我将在VI指南旁边打开该选项卡。:)
DemiSheep 2014年

4
在双括号内,不进行单词拆分,所以[[ $PACKAGENAME == "kakadu..." ]]可以。
glenn jackman 2014年

4
然而@glennjackman要注意的是,即使在双括号,你需要的右侧周围可变扩展双引号===并且!=,因为那边是一个模式,不是一个字符串。例如,foo='*'; [[ whatever = $foo ]]是真的。
吉尔斯(Gilles)'所以


4

另一种方法是否定它们:

: ${PACKAGENAME:?'$PACKAGENAME variable is empty!'} #emits error and exits
[ -z "${PACKAGENAME#kakadu-v6_4-00902C}" ] || { #if var - str not empty do block
    echo '$PACKAGENAME is not kakadu-v6_4-00902C' 
    exit 1
} >&2

上面的代码块首先测试if是否"$PACKAGENAME"有任何值,如果没有,则错误退出并回显?'this'}stderr。如果其父外壳仍然存在,则测试已通过,并且接下来测试是否从变量中删除“ kakadu ...”字符串会导致-z字符串为空。如果不是,则它再次发出错误并退出外壳。如果您的外壳此时在执行该块之后仍然存在,则不存在。

最好在函数中实现这种事情。喜欢:

argeq() ( i= : ${2?^MERR: not enough parameters!} #$#>=2 || quit w/ err ^M == \r
    z() { return $((${#1}>0)) ; } #return 1 if ${#1}>0 else 0
    until z "${2+?}" $((i=i+1)) #until $2 is not set...
    do  ! z "$1" && z "${1#"$2"}" || #$1 != '' && $1 - $2 == '' or...
        exit $((i${1:++1})) #exit $? == failed arg count
    shift ; done #shift away one param ; continue loop
)

使用该功能,您可以提供系统允许的尽可能多的参数。如果您提供的少于2个,它将返回1并向发送一条消息stderr。如果提供2个或更多参数,它将全部视为字符串,如果所有参数相同则返回0,而不是null,否则将返回参数编号,该编号首先会通过检查。

在您的情况下,可以像这样使用:

{   
    PACKAGENAME='kakadu-v6_4-00902C'
    argeq "$PACKAGENAME" kakadu-v6_4-00902C &&
        echo "kakadu-v6_4-00902C == $PACKAGENAME" ||
        echo failure
    ! argeq "${PACKAGENAME#*-}" kakadu-v6_4-00902C &&
        echo "kakadu-v6_4-00902C != ${PACKAGENAME#*-}" ||
        echo failure
}

###OUTPUT###
kakadu-v6_4-00902C == kakadu-v6_4-00902C
kakadu-v6_4-00902C != v6_4-00902C

为了进一步说明,我将编写另一个函数:

aeqecho() { i=$((i+1)) #inc for line#
    argeq "$@" && echo "$i : yay" || #allswell or
    ! e=$? ${2+:} return || #save $?; ! exclusive || to drop ERRs
    echo "$i : shite - arg$e failed" #report failure
}

演示:

{  i= s=string
   aeqecho $s #1
   aeqecho $s $s #2
   aeqecho "$s $s" #3
   aeqecho "$s $s" "${s} string" #4
   aeqecho "${s}1" $s string #5
   aeqecho "" "" "" #6
   aeqecho "" "$s" $s #7
   aeqecho 1 "${s#$s}1" $((2-1)) #8                     
   aeqecho $s $s $s $s $s $s $s $s $s $s $s $s stng #9  
   aeqecho $s $s $s $s $s $s $s $s $s $s $s $s string #10
}  

输出:

ERR: not enough parameters!
2 : yay
ERR: not enough parameters!
4 : yay
5 : shite - arg2 failed
6 : shite - arg1 failed
7 : shite - arg1 failed
8 : yay
9 : shite - arg13 failed
10 : yay
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.