SHELL-字符串操作和变量替换

SHELL-字符串操作和变量替换

1. 字符串操作(长度,读取,替换)

说明:* $substring可以是一个正则表达式

表达式 含义
${#string} 获取字符串 string 的长度
${string:position} 从字符串 string position 处截取子串
${string:position:length} 从字符串 string position 处截取length 长度的子串
${string#substring} 从字符串 string 的开头,删除最短匹配 substring 的子串
${string##substring} 从字符串 string 的开头,删除最长匹配 substring 的子串
${string%substring} 从字符串 string 的结尾,删除最短匹配 substring 的子串
${string%%substring} 从字符串 string 的结尾,删除最长匹配 substring 的子串
${string/substring/replacement} 在字符串 string 中,使用 replacement 替换 substring
${string//substring/replacement} 在字符串 string 中,使用 replacement,代替所有匹配的 substring
${string/#substring/replacement} 条件替换 : 如果字符串 string 的前缀匹配 substring , 那么就用 replacement 来代替匹配到的 substring
${string/%substring/replacement} 条件替换 : 如果字符串 string 的后缀匹配 substring ,那么就用 replacement 来代替匹配到的 substring

示例:

# 1) 获取变量长度
VAR="hello world"
echo ${#VAR}

[root@o18c tmp]# VAR="hello world"
[root@o18c tmp]# echo ${#VAR}
11

# 2) 通过索引下标截取子串
echo ${VAR:6}
echo ${VAR:6:3}

[root@o18c tmp]# echo ${VAR:6}
world
[root@o18c tmp]# echo ${VAR:6:3}
wor
[root@o18c tmp]#

VAR='https://www.mirrors163.com'
# 其中的 0 表示左边第一个字符开始,5 表示字符的总个数
echo ${VAR:0:5}
# 从左边第N个字符开始一直到结束
echo ${VAR:8}

# 从右边第N个字符开始往右边len个字符,用法:0-start:len
echo ${VAR:0-14:10}

# 从右边第N个字符开始一直到结束,用法:0-start
echo ${VAR:0-4}

[root@o18c tmp]# echo ${VAR:0:5}
https
[root@o18c tmp]# echo ${VAR:8}
www.mirrors163.com
[root@o18c tmp]#
[root@o18c tmp]# echo ${VAR:0-14:10}
mirrors163
[root@o18c tmp]# echo ${VAR:0-4}
.com
[root@o18c tmp]# 

# 3) 查找指定字符截取子串
VAR='https://www.mirrors163.com'
# 从左边开始找到字符 '//' 并将左边所有字符和自身删除,即保留其右边所有字符
echo ${VAR#*//}
echo ${VAR#*.}

# 从左边开始找到最右边一个的字符 '//' 并将左边所有字符和自身删除,即保留其右边所有字符字符
echo ${VAR##*.}

# 从右边开始找到字符 'www' 并将右边所有字符和自身删除,即保留其左边所有字符
echo ${VAR%www*}
echo ${VAR%.*}
# 从右边开始找到最左边一个的字符 '.' 并将右边所有字符和自身删除,即保留其左边所有字符字符
echo ${VAR%%.*}

# 是去掉左边字符(在键盘上 # 在 $ 之左边)
% 是去掉右边(在键盘上 % 在 $ 之右边)
单一符号是最小匹配﹔两个符号是最大匹配。
*是用来匹配不要的字符,也就是想要去掉的那部分
还有指定字符分隔号,与*配合,决定取哪部分
注意: 查找的字符串支持正则模式

[root@o18c tmp]# VAR='https://www.mirrors163.com'
[root@o18c tmp]# echo ${VAR#*//}
www.mirrors163.com
[root@o18c tmp]# echo ${VAR##*.} 
com
[root@o18c tmp]# echo ${VAR#*.}
mirrors163.com
[root@o18c tmp]# echo ${VAR%www*}
https://
[root@o18c tmp]# echo ${VAR%%.*}
https://www
[root@o18c tmp]# echo ${VAR%.*}
https://www.mirrors163
[root@o18c tmp]# echo ${VAR%%.*}
https://www
[root@o18c tmp]#

# 4) 变量替换
# 使用 'baidu' 替换 字符中的 'mirrors163'
echo ${VAR/mirrors163/baidu}
echo ${VAR/m/M}
# 使用 'M' 替换 字符中所有的字符 'm'
echo ${VAR//m/M}

[root@o18c tmp]# echo ${VAR/mirrors163/baidu}
https://www.baidu.com
[root@o18c tmp]# echo ${VAR/m/M}
https://www.Mirrors163.com
[root@o18c tmp]# echo ${VAR//m/M}
https://www.Mirrors163.coM
[root@o18c tmp]#

# 5) 匹配开头或结尾字符替换
str="apple, tree, apple tree"
echo ${str/#apple/APPLE}
echo ${str/%tree/TREE}

# 查找字符串str中 "apple"开头的子串并替换成 'APPLE'
[root@o18c tmp]# echo ${str/#apple/APPLE}
APPLE, tree, apple tree
[root@o18c tmp]# echo ${str/%apple/APPLE}
apple, tree, apple tree
# 查找字符串str中 "tree"结尾的子串并替换成 'TREE'
[root@o18c tmp]# echo ${str/%tree/TREE}
apple, tree, apple TREE
[root@o18c tmp]#

2. 判断读取字符串值(根据状态为变量赋值)

表达式 含义
${var} 变量var的值, 与$var相同
${var-DEFAULT} 如果var没有被声明, 那么就以$DEFAULT作为其值
${var:-DEFAULT} 如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值
${var=DEFAULT} 如果var没有被声明, 那么就以$DEFAULT作为其值
${var:=DEFAULT} 如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值
${var+OTHER} 如果var声明了, 那么其值就是$OTHER, 否则就为null字符串
${var:+OTHER} 如果var被设置了, 那么其值就是$OTHER, 否则就为null字符串
${var?ERR_MSG} 如果var没被声明, 那么就打印$ERR_MSG
${var:?ERR_MSG} 如果var没被设置, 那么就打印$ERR_MSG
${!var_prefix*} 匹配之前所有以var_prefix开头进行声明的变量
${!var_prefix@} 匹配之前所有以var_prefix开头进行声明的变量

示例:

VAR='liu'
DEFAULT='biao'

# 1) 如果VAR没有被声明, 那么就以$DEFAULT作为其值
echo ${VAR-$DEFAULT}
unset VAR
echo ${VAR-$DEFAULT}
unset VAR
echo ${VAR-'bi'}

[root@o18c tmp]# echo ${VAR-$DEFAULT}
liu
[root@o18c tmp]# unset VAR
[root@o18c tmp]# echo ${VAR-$DEFAULT}
biao
[root@o18c tmp]# unset VAR
[root@o18c tmp]# echo ${VAR-'bi'}
bi
[root@o18c tmp]#


# 2) 如果VAR没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值
VAR=''
echo ${VAR:-$DEFAULT}
VAR='liu'
echo ${VAR:-$DEFAULT}

[root@o18c tmp]# VAR=''
[root@o18c tmp]# echo ${VAR:-$DEFAULT}
biao
[root@o18c tmp]#

[root@o18c tmp]# VAR='liu'
[root@o18c tmp]# echo ${VAR:-$DEFAULT}
liu
[root@o18c tmp]#

# 3) 如果VAR声明了, 那么其值就是$OTHER, 否则就为null字符串
echo $VAR
OTHER='hi'
echo ${VAR+$OTHER}
echo $VAR
echo ${VAR+'hi'}

VAR='biao'
OTHER='hi'
echo ${VAR+$OTHER}
echo $VAR
echo ${VAR+'hi'}

[root@o18c tmp]# echo $VAR

[root@o18c tmp]# OTHER='hi'
[root@o18c tmp]# echo ${VAR+$OTHER}

[root@o18c tmp]# echo $VAR

[root@o18c tmp]# VAR='biao'
[root@o18c tmp]# OTHER='hi'
[root@o18c tmp]# echo ${VAR+$OTHER}
hi
[root@o18c tmp]# echo $VAR
biao
[root@o18c tmp]# echo ${VAR+'hi'}
hi
[root@o18c tmp]#

# 4) 如果VAR被设置了, 那么其值就是$OTHER, 否则就为null字符串
echo $VAR
echo $OTHER
echo ${VAR:+$OTHER}
VAR=''
echo ${VAR:+$OTHER}
unset VAR
echo ${VAR:+$OTHER}

[root@o18c tmp]# echo $VAR
biao
[root@o18c tmp]# echo $OTHER
hi
[root@o18c tmp]# echo ${VAR:+$OTHER}
hi
[root@o18c tmp]# VAR=''
[root@o18c tmp]# echo ${VAR:+$OTHER}

[root@o18c tmp]# unset VAR
[root@o18c tmp]# echo ${VAR:+$OTHER}

[root@o18c tmp]#

# 5) 如果VAR没被声明了, 那么就打印$ERR_MSG
ERR_MSG='hi, biao'
echo $VAR
echo ${VAR?$ERR_MSG}
unset VAR
echo ${VAR?$ERR_MSG}
VAR='biao'
echo ${VAR?$ERR_MSG}

[root@o18c ~]# ERR_MSG='hi, biao'
[root@o18c ~]# echo $VAR

[root@o18c ~]# echo ${VAR?$ERR_MSG}
-bash: VAR: hi, biao
[root@o18c ~]# echo $VAR

[root@o18c ~]# unset VAR
[root@o18c ~]# echo ${VAR?$ERR_MSG}
-bash: VAR: hi, biao
[root@o18c ~]# VAR='biao'
[root@o18c ~]# echo ${VAR?$ERR_MSG}
biao
[root@o18c ~]#

# 6) 如果VAR没被设置了, 那么就打印$ERR_MSG
ERR_MSG='hi, biao'
echo $VAR
echo ${VAR:?$ERR_MSG}
unset VAR
echo ${VAR:?$ERR_MSG}
VAR=''
echo ${VAR:?$ERR_MSG}

[root@o18c ~]# ERR_MSG='hi, biao'
[root@o18c ~]# echo $VAR
biao
[root@o18c ~]# echo ${VAR:?$ERR_MSG}
biao
[root@o18c ~]# unset VAR
[root@o18c ~]# echo ${VAR:?$ERR_MSG}
-bash: VAR: hi, biao
[root@o18c ~]# VAR=''
[root@o18c ~]# echo ${VAR:?$ERR_MSG}
-bash: VAR: hi, biao
[root@o18c ~]# 


# 7) 匹配当前环境中所有以VAR开头的变量
VAR1='liu'
VAR2='biao'
VAR3='liu biao'
echo ${!VAR@}
echo ${!VAR*}


[root@o18c tmp]# echo ${!VAR@}
VAR1 VAR2 VAR3
[root@o18c tmp]# echo ${!VAR*}
VAR1 VAR2 VAR3
[root@o18c tmp]#

3. 性能比较

在shell中,通过awk,sed,expr等都可以实现,字符串上述操作。下面我们进行性能比较。

$ test='/tmp/t.txt' 

$ time for i in $(seq 10000);do a=${#test}; done; 

$ time for i in $(seq 10000);do a=$(expr length$test); done; 

原文地址:https://www.cnblogs.com/binliubiao/p/12845742.html