首页 > 编程笔记 > Linux命令 阅读:9

Shell字符串的用法(非常详细)

Shell 字符串(String)其实是一系列字符的组合(如 abcd)。

在 Shell 脚本编程中,字符串是最常用的数据类型之一,只要不进行数学计算,甚至数字也可以看作字符串。

定义一个字符串可以由单引号' '引起来,也可以由双引号" "引起来,也可以不用引号。但是它们之间是有区别的:
Str1=xiaozhou
Str2='xiaozhou'
Str3="xiaozhou"
使用单引号' '的字符串,任何字符都会原样输出,在其中使用变量是无效的。字符串中不能出现单引号,即使对单引号进行转义也不行。

使用双引号" "的字符串,如果其中包含了某个变量,那么该变量将会被解析(得到该变量的值),而不是将变量名原样输出。字符串中可以出现双引号,只要它被转义了就可以。

不使用引号引用的字符串中,若出现变量也会被解析,这一点和使用双引号" "引用的字符串一样。但字符串中不能出现空格,否则空格后的字符串会被认为由其他变量或者命令解析。

【实例】3 种字符串定义形式。
[root@linux opt]# vim demo6.sh
#!/bin/bash
num=99
str1=c.biancheng.net$num
str2="shell \"script\" $num"
str3='C语言中文网:$num'
echo $str1
echo $str2
echo $str3

[root@linux opt]# bash demo6.sh
c.biancheng.net99
shell "script" 99
C语言中文网:$num
从示例中可以看出:

Shell获取字符串的长度

在 Shell 脚本中获取字符串的长度,语法格式如下:
${#string_name}
其中,string_name 表示字符串变量名。

【实例】获取字符串长度。
[root@linux opt]# vim demo7.sh
#!/bin/bash
str="https://c.biancheng.net/"
echo ${#str}

[root@linux opt]# bash demo7.sh
24

Shell字符串的拼接

字符串拼接在编写 Shell 脚本时候用得非常多,其过程也非常简单,有多简单呢?在拼接的过程中不需要使用任何运算符号,直接将两个字符串变量并排放在一起就实现拼接了。

【实例】字符串拼接。
[root@linux opt]# vim demo8.sh
#!/bin/bash
name="Shell"
url="https://www.c.biancheng.net/"
str1=$name$url          # 中间不能有空格
str2="$name $url"       # 如果用双引号引用,则中间可以有空格
str3=$name":"$url       # 中间可以出现别的字符串
str4="$name:$url"       # 这样写也可以
str5="${name}Script:${url}index.html"  # 需要给变量名加上大括号

echo $str1
echo $str2
echo $str3
echo $str4
echo $str5

[root@linux opt]# bash demo8.sh
Shellhttps://www.c.biancheng.net/
Shell https://www.c.biancheng.net/
Shell: https://www.c.biancheng.net/
Shell: https://www.c.biancheng.net/
ShellScript: https://www.c.biancheng.net/index.html 
在定义变量 str3 时,$name 和 $url 之间之所以不能出现空格,是因为当字符串不用任何一种引号引用时,遇到空格就认为字符串结束了,空格后的内容会被当作其他变量或命令解析。

在定义变量 str5 时,加{ }主要是为了帮助 bash 解释器识别变量的边界。

Shell字符串的截取

在编写某些特殊需求的 Shell 脚本时,字符串截取是一种常用且重要的操作。

Shell 截取字符串通常有两种方式:
先介绍第一种方式,从指定位置截取字符串。

从指定的位置截取字符串需要满足两个条件:
既然需要指定起始位置,那就涉及计数方向的问题,到底是从字符串左边开始计数,还是从字符串右边开始计数?答案是 Shell 支持两种计数方式。我们既可以从指定的位置往前面截取,也可以从指定的位置向后截取。

1) 从字符串左边开始计数:
${string:start:length}
其中,string 是要截取的字符串(一般为字符串变量名),start 是起始位置(左边开始,从 0 开始计数);length 是要截取的长度(省略的话表示直到字符串的末尾)。

2) 从字符串右边开始计数:
${string:0-start:length}
与上一种方式相比,语句中仅仅多了 0-,这是一种固定的写法,专门用来表示从字符串右边开始计数。

【实例】从字符串左边计数进行截取。
[root@linux opt]# vim demo9.sh
#!/bin/bash
url=c.biancheng.net
echo "写起始位置与截取长度:" ${url:2:9}
echo "只写起始位置:" ${url:2}

[root@linux opt]# bash demo9.sh
写起始位置与截取长度:biancheng
只写起始位置:biancheng.net

从字符串右边计数进行截取:
[root@linux opt]# vim demo10.sh
#!/bin/bash
url="c.biancheng.net"
echo ${url:0-13:9}
echo ${url:0-13}

[root@linux opt]# bash demo10.sh
iancheng.
biancheng.net
若选择从字符串右边计数进行截取,需要注意两点:
接下来介绍第二种截取字符串的方式:从指定字符开始截取。

从指定字符开始截取的方式是没办法指定字符串长度的,只能从指定的字符截取到字符串末尾。可以截取指定字符右边的所有字符,也可以截取字符左边的所有字符。

1) 使用“#”截取指定字符右边的所有字符:
${string#*chars}
其中,string 是要截取的字符串(一般为字符串变量名);chars 是指定的字符;*是通配符的一种,表示任意长度的字符串。

这里的 chars 是不会被截取的。


2) 使用“%”截取指定字符左边的所有字符:
${string%chars*}
重点注意一下星号(*)的位置,因为要截取 chars 左边的字符而忽略 chars 右边的字符,所以星号应该位于 chars 的右侧。其他用法和“#”相同。

【实例】使用“#”截取指定字符右边的所有字符(有3种写法)。
[root@linux opt]# vim demo11.sh
#!/bin/bash
url="https://c.biancheng.net/index.html"
echo "内容:"$url
echo "第一种截取写法" ${url#*t}
echo "第二种截取写法" ${url#*ttps}
echo "第三种截取写法" ${url#https://}

[root@linux opt]# bash demo11.sh
内容:https://c.biancheng.net/index.html
第一种截取写法 tps://c.biancheng.net/index.html
第二种截取写法 ://c.biancheng.net/index.html
第三种截取写法 c.biancheng.net/index.html

上面 3 种写法都是遇到第一个匹配的字符就结束了,我们做个实验匹配 URL 中的斜线,这个 URL 中有三条斜线,看一下结果匹配的是哪条斜线?
[root@linux opt]# vim demo12.sh
#!/bin/bash
url="https://c.biancheng.net/index.html"
echo "内容: "$url
echo ${url#*/}

[root@linux opt]# bash demo12.sh
内容: https://c.biancheng.net/index.html
/c.biancheng.net/index.html
通过实验可以看到,使用从指定字符开始截取的方式,匹配到的都是第一个符合条件的元素。如果希望直到最后一个指定字符(子字符串)匹配才结束,可以使用“##”,具体格式为
${string##*chars}
【实例】使用“#”和“##”分别进行截取。
[root@linux opt]# vim demo13.sh
#!/bin/bash
url="https://c.biancheng.net/index.html"
echo "内容:"$url
echo "使用#截取斜线“/”右边的所有字符:"${url#*/}
echo "使用##截取斜线“/”右边的所有字符:"${url##*/}

str="---aa+++aa@@@"
echo "内容:"$str
echo "使用#截取“aa”右边的所有字符:"${str#*aa}
echo "使用##截取“aa”右边的所有字符:"${str##*aa}

[root@linux opt]# bash demo13.sh  #执行此脚本
内容:https://c.biancheng.net/index.html
使用#截取斜线“/”右边的所有字符:/c.biancheng.net/index.html
使用##截取斜线“/”右边的所有字符:index.html
内容:---aa+++aa@@@
使用#截取“aa”右边的所有字符:+++aa@@@
使用##截取“aa”右边的所有字符:@@
由此可见,使用${string##*chars}是直到最后一个符合条件的匹配项才结束,而${string#*chars}是遇到第一个符合条件的匹配项就结束。

截取指定字符左边的所有字符:
[root@linux opt]# vim demo14.sh
#!/bin/bash
url="https://c.biancheng.net/index.html"
echo "内容:"$url
echo "使用%截取斜线“/”左边的所有字符:" ${url%/*}
echo "使用%%截取斜线“/”左边的所有字符:" ${url%%/*}

str="---aa+++aa@@@"
echo "内容:"$str
echo "使用%截取“aa”左边的所有字符:" ${str%aa*}
echo "使用%%截取“aa”左边的所有字符:" ${str%%aa*}

[root@linux opt]# bash demo14.sh
内容:https://c.biancheng.net/index.html
使用%截取斜线“/”左边的所有字符:https://c.biancheng.net
使用%%截取斜线“/”左边的所有字符:https:
内容:---aa+++aa@@@
使用%截取“aa”左边的所有字符:---aa+++
使用%%截取“aa”左边的所有字符:---

我们把以上字符串截取格式做一个汇总,见下表。

表:字符串截取格式汇总表
格 式 说 明
${string:start:length} 从 string 字符串的左边起始位置开始,向右截取 length 个字符
${string:start} 从 string 字符串的左边起始位置开始截取,直到最后
${string:0-start:length} 从 string 字符串的右边起始位置开始,向右截取 length 个字符
${string:0-start} 从 string 字符串的右边起始位置开始截取,直到最后
${string#*chars} 从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 右边的所有字符
${string##*chars} 从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 右边的所有字符
${string%*chars} 从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 左边的所有字符
${string%%*chars} 从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 左边的所有字符

相关文章