四、Shell变量之四变量的子串

一、变量的字串

${parameter}
返回变量$parameter的内容

${#parameter}
返回变量$parameter的内容长度(按字符)

${parameter:offset}
在变量${parameter}中,从位置offset之后开始提取字串的内容到结尾

${parameter:offset:length}
在变量${parameter}中,从位置offset之后开始提取长度为length的字串

${parameter#word}
从变量${parameter}开头开始删除最短匹配的word字串

${parameter##word}
从变量${parameter}开头开始删除最长匹配的word字串

${parameter%word}
从变量${parameter}结尾开始删除最短匹配的word字串

${parameter%%word}
从变量${parameter}结尾开始删除最长匹配的word字串

${parameter/pattern/string}
使用string代替第一个匹配的pattern

${parameter//pattern/string}
使用string代替所有匹配的pattern

案例1、取变量的长度

赋值ni hao da hai 给KING
[root@node1 tmp]# KING="ni hao da hai"
[root@node1 tmp]# echo $KING
ni hao da hai

打印变量值的长度
[root@node1 tmp]# echo ${#KING}
13
[root@node1 tmp]# echo $KING|wc -L
13
[root@node1 tmp]# expr length "$KING"
13
[root@node1 tmp]# echo $KING|awk '{print length($0)}'
13

#空格需要算一个字符

案例2:截取YWX变量的内容

[root@node1 tmp]# YWX="I am ywx linux, welcome to oldboy training"
[root@node1 tmp]# echo $YWX
I am ywx linux, welcome to oldboy training

从第2个字符之后开始截取,默认截取后面字符的全部,第2个字符不包含在内,也可理解为删除前面的多个字符。

[root@node1 tmp]# echo ${YWX:2}
am ywx linux, welcome to oldboy training

截取变量的内容,从第2个字符之后开始截取,截取2个字符。

[root@node1 tmp]# echo ${YWX:2:2}
am
[root@node1 tmp]# echo ${YWX}|cut -c 3-4
am

案例3、从变量$YWX内容的开头开始删除最短匹配“a*C”及“a*c”的子串。

[root@node1 tmp]# YWX=abcABC123ABCabc
[root@node1 tmp]# echo $YWX
abcABC123ABCabc
开头开始删除最短匹配“a*C”的子串。
[root@node1 tmp]# echo ${YWX#a*C}
123ABCabc
#从开头开始删除最短匹配“a*C”的子串。
开头开始删除最短匹配“a*c”的子串
[root@node1 tmp]# echo ${YWX#a*c}
ABC123ABCabc
#从开头开始删除最短匹配“a*c”的子串。

案例4、从变量$YWX开头开始删除最长匹配“a*C”及“a*c”的子串

[root@node1 tmp]# YWX=abcABC123ABCabc
[root@node1 tmp]# echo $YWX
abcABC123ABCabc
开头开始删除最长匹配“a*C”的子串。
[root@node1 tmp]# echo ${YWX##a*C}
abc
#从开头开始删除最长匹配“a*C”的子串。
开头开始删除最长匹配“a*c”的子串
[root@node1 tmp]# echo ${YWX##a*c}

[root@node1 tmp]# 
#开头开始删除最长匹配“a*c”的子串

案例5、从变量$YWX结尾开始删除最短匹配“a*C”及“a*c”的子串。

[root@node1 tmp]# YWX=abcABC123ABCabc
[root@node1 tmp]# echo $YWX
abcABC123ABCabc
从结尾开始删除最短匹配“a*C”的子串。
[root@node1 tmp]# echo ${YWX%a*C}
abcABC123ABCabc
#因为从结尾开始“a*C”没有匹配上任何子串,因此,没有删除任何字符,原样输出
从结尾开始删除最短匹配“a*c”的子串。
[root@node1 tmp]# echo ${YWX%a*c}
abcABC123ABC
#从结尾开始删除最短匹配“a*c”,即删除了结尾的abc三个字符。

案例6、从变量$YWX结尾开始删除最长匹配“a*C”及“a*c”的子串。

[root@node1 tmp]# YWX=abcABC123ABCabc
[root@node1 tmp]# echo $YWX
abcABC123ABCabc
从结尾开始删除最长匹配“a*C”的子串。
[root@node1 tmp]# echo ${YWX%%a*C}
abcABC123ABCabc
#因为从结尾开始“a*C”没有匹配上任何子串,因此,没有删除任何字符,原样输出
从结尾开始删除最短匹配“a*c”的子串。
[root@node1 tmp]# echo ${YWX%%a*c}

[root@node1 tmp]#
#从结尾开始删除最长匹配“a*c”的字符串,即删除全部字符。

删除匹配总结

有关上述匹配删除的小结:
·#表示从开头删除匹配最短。
·##表示从开头删除匹配最长。
·%表示从结尾删除匹配最短。
·%%表示从结尾删除匹配最长。
·a*c表示匹配的字符串,*表示匹配所有,a*c匹配开头为a、中间为任意多个字符、结尾为c的字符串。
·a*C表示匹配的字符串,*表示匹配所有,a*C匹配开头为a、中间为任意多个字符、结尾为C的字符串。

案例7、使用king字符串代替变量$YWX匹配的ywx字符串。

[root@node1 tmp]# YWX="I am ywx,yes,ywx,ywx"
[root@node1 tmp]# echo $YWX
I am ywx,yes,ywx,ywx
只替换最近的一个ywx
[root@node1 tmp]# echo ${YWX/ywx/king}
I am king,yes,ywx,ywx
替换全部的ywx
[root@node1 tmp]# echo ${YWX//ywx/king}
I am king,yes,king,king

二、Shell特殊扩展变量

${parameter:-word}
如果parameter的变脸值为空或未赋值,则返回word字符串并替代变量的值。用法:如果变量未定义,则返回备用值,防止变量为空值或因未定义而导致异常。

${parameter:=word}
如果parameter的变脸值为空或未赋值,则设置这个变脸值为word,并返回其值。位置变量和特殊变量不使用。用法:基本通${parameter:-word},但该变量又额外给parameter变脸赋值了。

${parameter:?word}
如果parameter的变脸值为空或未赋值,那么word字符串将被作为标准错误输出,否则输出变量的值。用法:用于捕捉由于变量未定义而导致的错误,并退出程序。

${parameter:+word}
如果parameter的变脸值为空或未赋值,则什么都不做,否则word字符串将替代变量的值

案例1、${parameter:-word}功能实践

${parameter:-word}的作用是如果parameter变量值为空或未赋值,则会返回word字符串替代变量的值。

[root@node1 tmp]# echo $test   #$test未赋值

[root@node1 tmp]# result=${test:-unset}
[root@node1 tmp]# echo $result
unset
[root@node1 tmp]# echo $test  

#对于${test:-UNSET},当test变量没值时,就返回变量结尾设置的UNSET字符串。
[root@node1 tmp]# test="kaka"
[root@node1 tmp]# echo $test
kaka
[root@node1 tmp]# result=${test:-unset}
[root@node1 tmp]# echo $result
kaka
#当test变量有值时,就打印result变量,返回test变量的内容。

案例2:${parameter:=word}功能实践

${parameter:=word}的作用是:如果parameter变量值为空或未赋值,就设置这个变量值为word,并返回其值。位置变量和特殊变量不适用。

[root@node1 tmp]# unset test
[root@node1 tmp]# unset result
[root@node1 tmp]# echo $test

[root@node1 tmp]# echo $result

[root@node1 tmp]# 
#取消test和result的赋值
[root@node1 tmp]# echo $test

[root@node1 tmp]# result=${test:=unset}
[root@node1 tmp]# echo $result
unset
[root@node1 tmp]# echo $test
unset
#最后会把unset赋值给test变量

[root@node1 tmp]# test="kaka"
[root@node1 tmp]# result=${test:=unset}
[root@node1 tmp]# echo $result
kaka

#当变量(result)值里的变量(test)值没有定义时,会给变量(result)赋值“:=”后面的内容,同时会把“:=”后面的内容赋值给变量(result)值里没有定义的变量(test)。这个变量的功能可以解决变量没有定义的问题,并确保没有定义的变量始终有值。

案例3、${parameter:?word}功能实践

{parameter:?word}的作用是:如果parameter变量值为空或未赋值,那么word字符串将被作为标准错误输出,否则输出变量的值。

[root@node1 tmp]# echo $key

[root@node1 tmp]# echo ${key:?not defined}
-bash: key: not defined
#key没有赋值则把not defined作为标准错误输出

[root@node1 tmp]# key=king
[root@node1 tmp]# echo ${key:?not defined}
king

案例4.${parameter:+word}功能实践

${parameter:+word}的作用是:如果parameter变量值为空或未赋值,则什么都不做,否则word字符串将替代变量的值。

[root@node1 tmp]# echo $seal

[root@node1 tmp]# echo ${seal:+word}

[root@node1 tmp]# 
#seal的值未空或没有赋值,则什么也不用做
[root@node1 tmp]# seal="nihao"
[root@node1 tmp]# echo ${seal:+word}
word
#如果变量有值,则打印word

案例5:实现Apache服务启动脚本/etc/init.d/httpd

yum install -y httpd

#!/bin/bash
#
# httpd        Startup script for the Apache HTTP Server
#..skip…
# Start httpd in the C locale by default.
HTTPD_LANG=${HTTPD_LANG-"C"} #<==如果HTTPD_LANG变量没有定义或为空,则打印HTTPD_
                                   LANG变量返回C值。
#<==这一步定义方法的目的是防止变量值为空或未定义。使用的是(${parameter-word}用法,
        此处省略了冒号)。
# This will prevent initlog from swallowing up a pass-phrase prompt if
# mod_ssl needs a pass-phrase from the user.
INITLOG_ARGS=""
# Set HTTPD=/usr/sbin/httpd.worker in /etc/sysconfig/httpd to use a server
# with the thread-based "worker" MPM; BE WARNED that some modules may not
# work correctly with a thread-based MPM; notably PHP will refuse to start.
# Path to the apachectl script, server binary, and short-form for messages.
apachectl=/usr/sbin/apachectl
httpd=${HTTPD-/usr/sbin/httpd}
#<==如果HTTPD变量没有定义或为空,则打印HTTPD_LANG变量返回/usr/sbin/httpd的值。
#<==此步定义方法的目的是防止变量值为空或未定义。使用的是(${parameter-word}用法,冒号省略了)。
prog=httpdpidfile=${PIDFILE-/var/run/httpd.pid}
lockfile=${LOCKFILE-/var/lock/subsys/httpd}
RETVAL=0…skip…
exit $RETVAL

案例6:删除7天前的过期数据备份。

如果忘记了定义path变量,又不希望path值为空值,就可以定义/tmp替代path空值的返回值

[root@oldboy test]# cat del.sh
find ${path - /tmp} -name "*.tar.gz" -type f -mtime +7|xargs rm -f
[root@oldboy test]# sh -x del.sh
+ xargs rm -f
+ find /tmp -name '*.tar.gz' -type f -mtime +7  #<==执行时,系统会自动删除/tmp下的文件。
如果忘了定义path变量,并且还未做特殊变量定义,那么命令就会出现意外
[root@oldboy tmp]# cat a.sh
find ${path} -name "*.tar.gz" -type f -mtime +7|xargs rm -f
[root@oldboy tmp]# sh -x a.sh
+ xargs rm -f
+ find -name '*.tar.gz' -type f -mtime +7 #<==这条命令明显没有指定路径,因此将会导致异常。
I have a dream so I study hard!!!
原文地址:https://www.cnblogs.com/yaokaka/p/13767204.html