九、字符串处理

 

 

 

大小写转化

 

# 把变量中的第一个字符换成大写
${test^}

# 把变量中的所有小写字母,全部替换为大写
${test^^}

# 把变量中的第一个字符换成小写
${test,}

# 把变量中的所有大写字母,全部替换为小写
${test,,}

 

示例

 

#!/bin/bash
# script file name is test.sh 
test="abcDEF"
echo "test^=${test^}"
echo "test^^=${test^^}"
echo "test,=${test,}"
echo "test,,=${test,,}"

 

如图:

 

 

 

获取字符串长度

 

${#string}

 


 

截取

 

字符串截取的方式:

字符串截取            格式                                           
使用${}表达式         ${var:起始位置:长度};编号从0开始,可省略                
使用expr substr      expr substr "$var" 起始位置 长度;起始位置编号从1开始
使用cut工具        echo $var | cut -b 起始位置-结束位置;起始位置编号从1开始

 

 

下面详细说明${}表达式 的用法

 

# 从string字符串的左边第start个字符开始(不包含第start个字符),向右截取到最后,start从0开始;
${string:start}

# 从string字符串的左边第start个字符开始(不包含第start个字符),向右截取length个字符;
${string:start:length}

# 从string字符串的右边第start个字符开始(包含第start个字符),向右截取到最后,start从1开始;
${string:0-start}

# 从string字符串的右边第start个字符开始(包含第start个字符),向右截取length个字符,start从1开始;
${string:0-start:length}

 

示例

 

#!/bin/bash
# script file name is test.sh 
url="https://blog.csdn.net/monarch91"
echo "url=${url}"
echo "url:8=${url:8}"
echo "url:8:4=${url:8:4}"
echo "url:0-8=${url:0-8}"
echo "url:0-8:4=${url:0-8:4}"
echo "url#*c=${url#*c}"
echo "url##*c=${url##*c}"
echo "url%c*=${url%c*}"
echo "url%%c*=${url%%c*}"

 

如图:

 

 

 

 

 

字符串切片实例:

    a='abcdefghijklmn'
    echo ${#a} #输出字符串a的总长度
    14
    echo ${a:4} #输出字符串a从0开始数,包含第4个元素之后的所有元素
    efghijklmn
    echo ${a:4:3} #输出字符串a从0开始数,包含第4个元素之后的3个元素
    efg
    echo ${a: -4} #从字符串a的右侧向左取4个元素,冒号后必须有一个空字符
    klmn
    echo ${a:5:-2} #输出字符串a从0开始数,包含第5个元素的向右数的i倒数3个元素,注意这种用法依赖bash版本,尽量别用。
    fghijkl
    echo ${a: -5:-2} #从字符串a的右侧向左数5个,再向右取到倒数3个字符,注意这种用法依赖bash版本,尽量别用。
    jkl
    echo ${a: -5:2} #从字符串a的右侧向左数5个,再向右取2个字符
    jk

 

 

 

 

 

 

 

字符串的匹配删除

 

 

# 从string字符串左边第一次出现*chars的位置开始,截取*chars右边的所有字符,不包含chars;
${string#*chars}

# 从string字符串左边最后一次出现*chars的位置开始,截取*chars右边的所有字符,不包含chars;
${string##*chars}

# 从string字符串右边第一次出现chars*的位置开始,截取chars*左边的所有字符,不包含chars;
${string%chars*}

# 从string字符串右边最后一次出现chars*的位置开始,截取chars*左边的所有字符,不包含chars;
${string%%*chars*}

 

 

 

解析:

${string#substring}    从变量$string的开头, 删除最短匹配$substring的子串
${string##substring}    从变量$string的开头, 删除最长匹配$substring的子串
${string%substring}    从变量$string的结尾, 删除最短匹配$substring的子串
${string%%substring}    从变量$string的结尾, 删除最长匹配$substring的子串

 

${var#*word}:其中word可以是指定的任意字符功能:自左而右,查找var变量所存储的字符串中,第一次出现的word, 删除字符串开头至第一次出现word字符之间的所有字符
${var##*word}:同上,贪婪模式,不同的是,删除的是字符串开头至最后一次由word指定的字符之间的所有内容
${var%word*}:其中word可以是指定的任意字符;功能:自右而左,查找var变量所存储的字符串中,第一次出现的word, 删除字符串最后一个字符向左至第一次出现word字符之间的所有字符;
${var%%word*}:同上,只不过删除字符串最右侧的字符向左至最后一次出现word字符之间的所有字符;

 

字符处理实例:

 

a='abcdefg_a_fghijklmn'
echo ${a#*fg} #从左边开始删,删除起始位置到第一个fg为止,包括fg
_a_fghijklmn
echo ${a##*fg} #贪婪模式,左边开始删,删除起始位置到最后一个fg为止,包括fg
hijklmn
echo ${a%fg*} #从右边开始删,删除终点位置到第一个fg为止,包括fg
abcdefg_a_
echo ${a%%fg*} #贪婪模式,从右边开始删,删除重点位置到最后一个fg为止,包括fg
abcde

 例子2:

#!/bin/bash
# script file name is test.sh 
url="https://blog.csdn.net/monarch91"
echo "url=${url}"
echo "url#*c=${url#*c}"
echo "url##*c=${url##*c}"
echo "url%c*=${url%c*}"
echo "url%%c*=${url%%c*}"

 

 

 

字符串的替换

 

${string/substring/replacement}     使用replacement, 来代替第一个匹配的$substring
${string//substring/replacement}     使用replacement, 代替所有匹配的substring
${string/#substring/replacement}     如果string的前缀匹配substring, 那么就用replacement来代替匹配到的substring
${string/%substring/replacement}     如果string的后缀匹配substring, 那么就用replacement来代替匹配到的substring

 ${var/pattern/substr}:查找var所表示的字符串中,第一次被pattern所匹配到的字符串,以substr替换之
${var//pattern/substr}: 查找var所表示的字符串中,所有能被pattern所匹配到的字符串,以substr替换之
${var/#pattern/substr}:查找var所表示的字符串中,行首被pattern所匹配到的字符串,以substr替换之
${var/%pattern/substr}:查找var所表示的字符串中,行尾被pattern所匹配到的字符串,以substr替换之

 

查找替换实例:

a='abcdefg_a_fghijklmn'
echo ${a/fg/dd} #替换从左边数第一个fg为dd
abcdedd_a_fghijklmn
echo ${a//fg/dd} #替换字符串中所有的fg为dd
abcdedd_a_ddhijklmn
echo ${a/#ab/dd} #如果开头是ab则替换成dd
ddcdefg_a_fghijklmn
echo ${a/#fd/dd} #如果开头是fd则替换成dd
abcdefg_a_fghijklmn #开头不是fd不做替换
echo ${a/%mn/dd} #结尾是mn则替换成dd
abcdefg_a_fghijkldd
echo ${a/%fd/dd} #如果结尾是fd则替换成dd
abcdefg_a_fghijklmn #结尾并不是fd不做替换

 

 

 

变量初值处理

 

 

# 若变量var为空,则用string来替换此处的值,最常用。
${var:-string}

# 若变量var为空,则用string来替换此处的值,把string赋给变量var。
${var:=string}

# 若变量var不为空,则用string来替换此处的值。
${var:+string}

# 若变量var不为空,则用string来替换此处的值;
# 若变量var为空,则把string输出到标准错误中,并从脚本中退出。
# 常用利用此特性来检查是否设置了变量的值。
${var:?string}

 

 

取值

 

 

取值,${var:-word}

 

 


若变量var已存在且非null,则返回$var的值
否则返回字串"word",变量var值不变
用途: 如果变量没定义 返回默认值

 

 

赋值

 

赋值,${var:=word}

若变量var已存在且非null,则返回$var的值
否则返回字串"word",并赋值给变量var
用途: 如果变量没定义 给变量赋值

 

 

 

 

 

有值时提示

 

 

 

有值时提示,${var:+"提示信息"}

若变量var已存在且非null,则给出提示
否则返回NUll(空值)
用途 : 测试变量是否定义

 

 

 

无值时提示

 

 

 

无值时提示,${var:?"提示信息"}

若变量var已存在且非null,则返回$var的值
否则给出提示信息(若省略,则用默认提示)
用途: 捕捉由于变量未定义所导致的错误

 

 

 

 

下面一次举例说明:

1${value:-word}  

当变量未定义或者值为空时,返回值为word内容,否则返回变量的值

举例:

[zgy@Web ~]$ result=${test:-UNSET}

[zgy@Web ~]$ echo $result

UNSET

[zgy@Web ~]$ echo $test

            ==>这里是空

 


结论:当test变量没内容时,就返回了后面的UNSET.

 

[zgy@Web ~]$ test='oldboy'

[zgy@Web ~]$ result=${test:-UNSET}

[zgy@Web ~]$ echo $result

Oldboy

 


提示:这个变量可以用来判断变量是否没有定义

 

(2)${value:=word}  

[zgy@Web ~]$ unset result

[zgy@Web ~]$ echo $result

 

[zgy@Web ~]$ unset test

[zgy@Web ~]$ echo $test

 

[zgy@Web ~]$ result=${test:=UNSET}

[zgy@Web ~]$ echo $result

UNSET

[zgy@Web ~]$ echo $test

UNSET

[zgy@Web ~]$ test=oldboy

[zgy@Web ~]$ result=${test:=UNSET}

[zgy@Web ~]$ echo $result

oldboy

[zgy@Web ~]$ echo $test

Oldboy

 


提示:这个变量功能可以解决变量没有定义的问题,确保变量始终有值

 

(3)${value:?”word”}  

[zgy@Web ~]$ echo ${value:?"not defined"}

-bash: value: not defined

[zgy@Web ~]$ value=1

[zgy@Web ~]$ echo ${value:?"not defined"}

1

[zgy@Web ~]$ unset value

[zgy@Web ~]$ echo ${value:?"not defined"}

-bash: value: not defined

 

提示:用于捕捉由于未定义而导致的错误,如:"not defined"

 

 

(4)${var:+word}  

[zgy@Web ~]$ r=${value:+1}

[zgy@Web ~]$ echo $r

 

[zgy@Web ~]$ value=oldboy

[zgy@Web ~]$ echo $r

 

[zgy@Web ~]$ r=${value:+1}

[zgy@Web ~]$ echo $r

1

 


提示:此功能可用于测试变量是否存在。

 

 

(5){value:-word}去掉冒号

[zgy@Web ~]$ httpd=${HTTPD-/usr/sbin/httpd}

[zgy@Web ~]$ pidfile=${PIDFILE-/var/run/httpd,pid}

[zgy@Web ~]$ echo $httpd $pidfile

/usr/sbin/httpd /var/run/httpd,pid

[zgy@Web ~]$ echo $HTTPD $PIDFILE

 

 

 

结论:变量没定义就用-号后面的替代

 

 

 

 

(6)应用例子:/etc/init.d/httpd(注意红色部分)

apachectl=/usr/sbin/apachectl

httpd=${HTTPD-/usr/sbin/httpd}

prog=httpd

pidfile=${PIDFILE-/var/run/httpd/httpd.pid}

lockfile=${LOCKFILE-/var/lock/subsys/httpd}

RETVAL=0

 

 

 

提示:用yum安装的httpd

系统服务crond脚本使用案例:/etc/init.d/crond

 

如图:

 

 

(2)${value:=word}

与前者类似,只是若变量未定义或者值为空时,在返回word的值的同时将word赋值给value

[root@Web ~]# OLD=${value:=word}

[root@Web ~]# echo $OLD

word

[root@Web ~]# echo $value

word

[root@Web ~]# value="test"

[root@Web ~]# OLD=${value:=word}

[root@Web ~]# echo $OLD

test

[root@Web ~]# echo $value

test

 

 

注:变量替换的值也可以是``括起来的命令:$USERDIR={$Mydir:-`pwd`}

 

 

(3)${value:?message}

 若变量以赋值的话,正常替换。否则将消息message送到标准错误输出(若此替换出现在shell程序中,那么该程序将中止运行)

生产应用场景:

1)/etc/init.d/httpd

2)/etc/init.d/crond

3)对变量的路径进行操作,最好先判断路径是否为空。特别是删除操作,容易有危险。

[root@Web ~]#sed -i ‘1d’d.sh

[root@Web ~]# cat d.sh

path=/server/backup

find ${path:=/tmp/} -name “*.tar.gz” -type f | xargs rm -f

[root@Web ~]#sh -x d.sh

 

 

 

变量的处理计算变量长度与其他不同方法的耗时对比:

[root@Web ~]# chars=`seq -s " " 100`

[root@Web ~]# echo $chars

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

[root@Web ~]# echo ${#chars}

291

[root@Web ~]# echo $chars|wc -m

292

[root@Web ~]# echo $(expr length "$chars")

291

[root@Web ~]# time for i in $(seq 11111);do count=${#chars};done;

 

real 0m0.671s

user 0m0.950s

sys 0m0.002s

[root@Web ~]# time for i in $(seq 11111);do count=`echo ${chars}|wc -m`;done;

 

real 0m27.419s

user 0m1.021s

sys 0m4.189s

[root@Web ~]# time for i in $(seq 11111);do count=`echo expr length "${chars}"`;done;

 

real 0m6.513s

user 0m0.346s

sys 0m1.376s

 

 

  我们看到速度相差几十到上百倍,一般情况调用外部命令处理,与内置功能操作性能相差较大。在shell编程中,我们应尽量用内置操作或函数完成。

 

 

补充

 

当然,除了以上操作,Shell还有许多字符串操作,下面小编为大家整理了一些,需要的可以参考一下

字符串的拼接

 

str1=www
str2=bilibili

string1=$str1$str2              #中间不加别的,直接放一起
string2="$str1 $str2"           #双引号括住,中间可加任意字串
string3=$str1"..."$str2         #整体不加引号,若中间要出现别的字串需前后紧挨,且字串双引号括住
string4="${str1}.${str2}.com"   #也可以使用${}方式引用变量

echo $string1
echo $string2
echo $string3
echo $string4

 

运行结果:

 

wwwbilibili
www bilibili
www...bilibili
www.bilibili.com

 

读取字符串

 

$ echo ${abc-'ok'}
ok

$ echo $abc
$ echo ${abc='ok'}
ok
$ echo $abc
ok

$ var1=11;var2=12;var3=
$ echo ${!v@}
var1 var2 var

$ echo ${!v*}
var1 var2 var3

 

 

字符串比较

 

[[ "a.txt" == a* ]]        #逻辑真(pattern matching)
[[ "a.txt" =~ .*\.txt ]]   #逻辑真(regex matching)
[[ "abc" == "abc" ]]       #逻辑真(string comparision)
[[ "11" < "2" ]]           #逻辑真(string comparision),按 ascii 值比较

 

posted @ 2018-05-03 13:28  钟桂耀  阅读(303)  评论(0编辑  收藏  举报