Linux Shell 字符串操作详解

一、判断读取字符串值:

表达式 含义
${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 *
${!varprefix*} 匹配之前所有以 varprefix 开头进行声明的变量
${!varprefix@} 匹配之前所有以 varprefix 开头进行声明的变量

* 的意思是:当然,如果变量 var 已经被设置的话,那么其值就是 $var 。

示例:

以下示例的运行环境为:CentOS Linux 7.5.1804

( 1 )${var-DEFAULT}  的使用:

这里需要注意的是 DEFAULT 不是变量的引用,仅仅只是一个字符串。

[root@host ~]# cat test.sh 
echo 1.${var-DEFAULT}
var=""
echo 2.${var-DEFAULT}
[root@host ~]# 
[root@host ~]# sh test.sh 
1.DEFAULT
2.
[root@host ~]#

( 2 )${var=DEFAULT} 的使用:

这里需要注意的是 DEFAULT 不是变量的引用,仅仅只是一个字符串。

再来看另一个示例,就算定义了 DEFAULT 变量,但是不加 $ 符号引用,输出结果以上例相同:

[root@host ~]# cat test.sh 
DEFAULT="DEF"
echo 1.${var=DEFAULT}
var=""
echo 2.${var=DEFAULT}
[root@host ~]# 
[root@host ~]# sh test.sh 
1.DEFAULT
2.
[root@host ~]#

( 3 )${var=$DEFAULT} 的使用:

这里需要注意的是 DEFAULT 是变量的引用。

[root@host ~]# cat test.sh 
DEFAULT="DEF"
echo 1.${var=$DEFAULT}
var=""
echo 2.${var=$DEFAULT}
var="VAR"
echo 3.${var=$DEFAULT}
[root@host ~]# 
[root@host ~]# sh test.sh 
1.DEF
2.
3.VAR
[root@host ~]#

( 4 )${var:=$DEFAULT} 的使用:

这里需要注意的是 DEFAULT 是变量的引用。

[root@host ~]# cat test.sh 
DEFAULT="DEF"
echo 1.${var:=$DEFAULT}
var=""
echo 2.${var:=$DEFAULT}
var="VAR"
echo 3.${var:=$DEFAULT}
[root@host ~]# 
[root@host ~]# sh test.sh 
1.DEF
2.DEF
3.VAR
[root@host ~]#

( 5 )${var+$OTHER} 的使用:

这里需要注意的是 OTHER 是变量的引用。

[root@host ~]# cat test.sh 
OTHER="OTH"
echo 1.${var+$OTHER}
var=""
echo 2.${var+$OTHER}
var="VAR"
echo 3.${var+$OTHER}
[root@host ~]# 
[root@host ~]# sh test.sh 
1.
2.OTH
3.OTH
[root@host ~]#

( 6 )${var:+$OTHER} 的使用:

这里需要注意的是 OTHER 是变量的引用。

[root@host ~]# cat test.sh 
OTHER="OTH"
echo 1.${var:+$OTHER}
var=""
echo 2.${var:+$OTHER}
var="VAR"
echo 3.${var:+$OTHER}
[root@host ~]# 
[root@host ~]# sh test.sh 
1.
2.
3.OTH
[root@host ~]#

( 7 )${var:?$ERR_MSG} 的使用:

这里需要注意的是 ERR_MSG 是变量的引用。

[root@host ~]# cat test.sh 
ERR_MSG="ERR_MESSAGE"
echo ${var:?$ERR_MSG}
[root@host ~]# 
[root@host ~]# sh test.sh 
test.sh: line 2: var: ERR_MESSAGE
[root@host ~]#

接下来的示例是定义了 var 变量,但 var 变量为空:

[root@host ~]# cat test.sh 
ERR_MSG="ERR_MESSAGE"
var=""
echo ${var:?$ERR_MSG}
[root@host ~]# 
[root@host ~]# sh test.sh 
test.sh: line 3: var: ERR_MESSAGE
[root@host ~]#

接下来的示例是定义了 var 变量,var 变量有值:

[root@host ~]# cat test.sh 
ERR_MSG="ERR_MESSAGE"
var="VAR"
echo ${var:?$ERR_MSG}
[root@host ~]# 
[root@host ~]# sh test.sh 
VAR
[root@host ~]#

( 8 )${!varprefix*} 和 ${!varprefix@} 的使用:

[root@host ~]# cat test.sh 
abc="ABC"
bbc="BBC"
abd="ABD"
echo 1.${!ab*}
echo 2.${!ab@}
[root@host ~]# 
[root@host ~]# sh test.sh 
1.abc abd
2.abc abd
[root@host ~]#

二、字符串操作(计算):

示例:

( 1 )用字符串做加法:

字符串变量 count 为 “ 1 ”,对 count 做加 1 的操作,并打印结果:

[root@host tmp]# cat test.sh 
count="1"
count=$(expr $count + 1)
echo $count
[root@host tmp]# 
[root@host tmp]# sh test.sh 
2
[root@host tmp]#

三、字符串操作(长度 、读取 、替换):

表达式 含义
${#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} 使用 $replacement ,来代替第一个匹配的 $substring
${string//substring/replacement} 使用 $replacement ,代替所有匹配的 $substring
${string/#substring/replacement} 如果 $string 的前缀匹配 $substring ,那么就用 $replacement 来代替匹配到的 $substring
${string/%substring/replacement} 如果 $string 的后缀匹配 $substring ,那么就用 $replacement 来代替匹配到的 $substring

示例:

( 1 )截取字符串的最后一个字符:

[root@root tmp]# cat test.sh 
str="123456"
str=${str:0:$(expr ${#str} - 1)}
echo $str

str="1234567890"
str=${str:0:$(expr ${#str} - 1)}
echo $str
[root@root tmp]# 
[root@root tmp]# sh test.sh 
12345
123456789
[root@root tmp]#

四、字符串的操作(连接):

示例:

( 1 )字符串的连接:

[root@host ~]# cat test.sh 
#!/bin/sh
a="A"
b="B"
echo $a$b
[root@host ~]# 
[root@host ~]# sh test.sh 
AB
[root@host ~]#

( 2 )接下来的例子有两个存放带有换行符的变量 A_LIST 和 D_LIST ,重点在于 echo $LIST 和 echo “$LIST” 输出时的不同:

  1. 如果使用 echo $a 输出变量,则变量中的换行都会被忽略掉,所有内容输出到一行;
  2. 而使用 echo “$a” 可正常输出变量中的换行。
[root@host ~]# cat test.sh 
#!/bin/sh
A_LIST="A
B
C"
D_LIST="D
E
F"
LIST=${A_LIST}"
"${D_LIST}
echo $LIST
echo =============
echo "$LIST"
[root@host ~]# 
[root@host ~]# sh test.sh 
A B C D E F
=============
A
B
C
D
E
F
[root@host ~]#

五、字符串的操作( 字符串与 echo 命令的使用):

示例:

( 1 )使用 echo -e 处理特殊字符:

[root@host ~]# cat test.sh 
text="A\nB"
echo $text
echo =====
echo -e $text
[root@host ~]# 
[root@host ~]# sh test.sh 
A\nB
=====
A
B
[root@host ~]#

常用的特殊字符有:

  1. \a 发出警告声;
  2. \b 删除前一个字符;
  3. \c 最后不加上换行符号;
  4. \f 换行但光标仍旧停留在原来的位置;
  5. \n 换行且光标移至行首;
  6. \r 光标移至行首,但不换行;
  7. \t 插入 tab ;
  8. \v 与 \f 相同;
  9. \ 插入 \ 字符;
  10. \nnn 插入 nnn(八进制)所代表的 ASCII 字符。

( 2 )使用 echo -n 不换行输出:

[root@host ~]# cat test.sh 
echo A
echo B
echo =====
echo -n A
echo B
[root@host ~]# 
[root@host ~]# sh test.sh 
A
B
=====
AB
[root@host ~]#

( 3 )输出字符串到文件(覆盖源文件):

如下例所示,使用命令 echo string > file ,文件 file 的内容会被替换成字符串 string :

[root@host ~]# cat test.txt 
123
[root@host ~]# 
[root@host ~]# echo 456 > test.txt
[root@host ~]# 
[root@host ~]# cat test.txt 
456
[root@host ~]#

( 4 )输出字符串到文件(追加到源文件的最后一行):

如下例所示,使用命令 echo string >> file ,字符串 string 会被追加到文件 file 的最后一行:

[root@host ~]# cat test.txt 
123
[root@host ~]# 
[root@host ~]# echo 456 >> test.txt
[root@host ~]# 
[root@host ~]# cat test.txt 
123
456
[root@host ~]#

( 5 )将带有换行符的字符串输出到文件:

这里需要注意的是命令 echo 后边使用的是单引号,而非双引号。

[root@host ~]# cat test.txt 
123
[root@host ~]# 
[root@host ~]# cat test.sh 
echo '456
789' >> test.txt
[root@host ~]# 
[root@host ~]# sh test.sh 
[root@host ~]# 
[root@host ~]# cat test.txt 
123
456
789
[root@host ~]#

 

参考自:

  • https://www.cnblogs.com/gaochsh/p/6901809.html
打赏作者
这里是 “ CCIE 工程师社区 ” 官方的捐款通道,您是否可以考虑请我们喝杯咖啡呢?

您的支持将鼓励我们继续创作!

[微信] 扫描二维码打赏

[支付宝] 扫描二维码打赏

Was this article helpful?

Related Articles

Leave A Comment?

This site uses Akismet to reduce spam. Learn how your comment data is processed.