字符串顺序及大小比较注意事项

字符串顺序及大小比较注意事项

字符串顺序

当要使用测试条件的大于或小于功能时,会出现两个经常困扰 shell 程序员的问题
1. 大于号和小于号必须转义,否则 shell 会将大于和小于号(>, <)当作重定向符号,把字符串值当作文件名

#cat badtest.sh
#!/bin/bash
# mis-using string comparisons
#
v1=baseball
v2=hockey
#
if [ $v1 > $v2 ]
then
    echo "$v1 is greater than $v2"
else
    echo "$v1 is less than $v2"
fi

#sh badtest.sh 
baseball is greater than hockey

badtest.sh 脚本中使用大于号来比较字符串,执行脚本未报错,但结果是错的。脚本将大于号解释成输出重定向。因此创建了一个名为 hockey 的文件。由于重定向的完成,test 命令返回退出状态码 0, if 语句便以为所有命令成功结束,从而执行 then 部分语句。

要解决此问题,需要对大于号进行转义

#cat test9.sh 
#!/bin/bash
# mis-using string comparisons
#
v1=baseball
v2=hockey
#
if [ $v1 \> $v2 ]
then
    echo "$v1 is greater than $v2"
else
    echo "$v1 is less than $v2"
fi

#sh test9.sh 
baseball is less than hockey
  1. 大于和小于顺序和 sort 命令所采用的不同
    sort 命令处理大写字母的方法和 test 命令相反
#cat test9b.sh 
#!/bin/bash
# testing string sort order
v1=Testing
v2=testing
#
if [ $v1 \> $v2 ]
then
    echo "$v1 is greater than $v2"
else
    echo "$v1 is less than $v2"
fi

#sh test9b.sh 
Testing is less than testing
#cat testfile 
Testing
testing

#sort testfile 
testing
Testing

在脚本 test9b.sh 的比较测试中,大写字母被认为是小于小写字母的。但 sort 命令对 testfile 文件内容的排序与之相反,当做同样的字符串放进文件中并用sort排序时,小写字母会先出现。

比较测试和 sort 命令结果不一致原因
二者所采用的排序技术不同,比较测试遵循的是每个字符的ASCII数值,而sort命令使用的是系统的本地化语言设置中定义的排序顺序。对于英语,本地化设置指定了在排序顺序中小写字母出现在大写字母前

说明
test命令和测试表达式使用标准的数学比较符号来表示字符串比较,而用文本代码来表示数值比较。这个细微的特性被很多程序员理解反了。如果你对数值使用了数学运算符号, shell会将它们当成字符串值,可能无法得到正确的结果。

字符串大小

-n and -z可检查一个变量是否含有数据

比较描述
-n str1检查str1的长度是否大于0
-z str1检查str1的长度是否等于0

变量分为三种情况

变量
1有值,如'string'
2为空,如''
3未定义变量
测试方法

对变量的三种情况分别以选项-n and -z测试

#cat test10.sh 
#!/bin/bash
# testing string length
var1=testing
var2=''

#
if [ -n $var1 ]
then 
    echo "-n option, The string '$var1' is not empty"  
else
    echo "-n option, The string '$var1' is empty"
fi

if [ -z $var1 ]
then
    echo "-z option, The string '$var1' length is 0"
else
    echo "-z option, The string '$var1' is not empty"
fi

#
if [ -n $var2 ]  
then
    echo "-n option, The string '$var2' is not empty'"
else
    echo "-n option, The string '$var2' is empty"
fi

if [ -z $var2 ]
then
    echo "-z option, The string '$var2' length is 0"
else 
    echo "-z option, The string '$var2' is not empty"
fi
#
if [ -n $var3 ]
then
    echo "-n option, The string '$var3' is not empty"
else
    echo "-n option, The string '$var3' is empty"
fi

if [ -z $var3 ]
then
    echo "The string '$var3' length is 0"
else
    echo "The string '$var3' is not empty"
fi

这个例子创建了两个字符串变量。 val1变量包含了一个字符串, val2变量包含的是一个空
字符串。后续的比较如下:
if [ -n $val1 ]
判断val1变量是否长度非0,而它的长度正好非0,所以then部分被执行了。
if [ -z $val1 ]
判断val1变量是否长度为0,而它的长度非0,所以else部分被执行了。
if [ -n $var2 ]
if [ -z $var2 ]
判断val2变量是否长度为0,而它正好长度为0,所以then部分被执行了。
if [ -n $val3 ]
if [ -z $val3 ]
判断val3变量是否长度为0。这个变量并未在shell脚本中定义过,所以它的字符串长度仍然为0,尽管它未被定义过。

存在问题

对空字符串和未定义变量的长度计算需注意
if [ -n $var2 ]
if [ -n $var3 ]

空字符串长度比较测试

#cat empty_str_len.sh 
#!/bin/bash
#
v1=''
#
if [ -n $v1 ]
then
    echo "The length of $v1 is greater than 0"
else
    echo "The length of $v1 is less than 0"
fi

#sh empty_str_len.sh 
The length of  is greater than 0

未定义变量长度比较测试

#cat empty_str_len.sh 
#!/bin/bash
#
v1=''
#
if [ -n $v2 ]
then
    echo "The length of $v1 is greater than 0"
else
    echo "The length of $v1 is less than 0"
fi

#sh empty_str_len.sh 
The length of  is greater than 0

结论
-n str 认为空字符串和未定义变量的长度是大于0的

窍门
空的和未初始化的变量会对shell脚本测试造成灾难性的影响。如果不是很确定一个变量的内容,最好在将其用于数值或字符串比较之前先通过-n或-z来测试一下变量是否含有值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值