shell 变量、字符串的处理方法

简介

    字符串是由一个或多个字符组成的数据类型。在编程中,字符串常用于存储和处理文本数据,可以使用单引号(’ ')或双引号(" ")括起来。

      

目录

1. 字符串的基础

1.1. 字符串引号的区别

1.2. 如何在引号中输出引号

1.3. 使用引号赋值变量

2. 字符串变量的高级用法

2.1. 按索引截取字符串

2.2. 按分隔符截取字符串

2.3. 判断变量是否存在

2.4. 转换字母大小写

2.5. 替换字符


        

1. 字符串的基础

1.1. 字符串引号的区别

在学习处理字符串方法之前,需要了解一些基本知识。比如我们平时在写代码时,一般不区分单引号、双引号,但在 shell 中,单引号和双引号在解释上有一些区别,先来看一个例子:

使用 echo 分别使用单引号和双引号输出字符串,这里看起来是一样的。

        

我们来看下一个例子,输出变量

shell 变量、字符串的处理方法_第1张图片

这时可以发现使用单引号,里面是什么字符就输出什么字符;使用双引号则可以进行变量替换。所以两种引号有这么一些区分:

  1. 单引号不会解释特殊符号,会直接按字面输出;
  2. 双引号可以解释特殊符号,包括:变量${ }、命令$( )、命令` ` 等。

总结:如果需要输出带有特殊字符的纯文本,使用单引号最佳;如果需要输出某些变量时,使用双引号最佳。

        

1.2. 如何在引号中输出引号

在了解了单引号和双引号的区别后,那么下一个问题又来了,引号中怎么输出引号呢?这里列举了几种方式,懂得伙伴直接跳过。

        

【案例一】单引号中输出单引号(目标 输出 id: 'a001' )

按我们平时思维,在引号中在放一个引号那么就可以输出,我们先来试试

echo 'id: 'a001' '

但是在 shell 的单引号字符串中,单引号字符被视为特殊字符,用于将字符串中的内容标记为一个整体。所以这种方式是不可行的(下图不符合预期)

在单引号字符串中使用转义字符 \ 来表示单引号字符本身,即 \' 表示一个单引号字符。所以正确的使用方法是 '\'' ,来看一下例子

echo 'id: '\''a001'\'' '

符合预期

        

【案例二】单引号中输出双引号(目标 输出 id: "a001" )

单引号中嵌套双引号是可以正常使用的

echo 'id: "a001" '

        

【案例三】双引号中输出单引号(目标 输出 id: 'a001' )

双引号中嵌套单引号也是正常的

echo "id: 'a001' "

        

【案例四】双引号中输出双引号(目标 输出 id: "a001" )

与《案例一》不同的是,双引号中支持各种转义符,所以我们直接对双引号进行转义即可

echo "id: \"a001\" "

        

【案例五】输出嵌套引号(目标 输出 id: "a001: 'a001.1: "b001" ' " )

echo "id: \"a001: 'a001.1: \"b001\" ' \" "

这条命令看起来老壳疼,实际上理解了就很简单。我们知道,在双引号中是可以使用单引号的,如果在双引号中使用双引号那么需要使用转义符 \" ,说到这里再看一眼命令就明白了。

shell 变量、字符串的处理方法_第2张图片

        

1.3. 使用引号赋值变量

前面讲了不同引号的区别和引号中包含引号,这其实也是与赋值给变量有关系的。比如给变量赋值另一个变量的结果(引号的方式是一样的)

v1="AAA"
v2="BBB ${v1}"

shell 变量、字符串的处理方法_第3张图片

        

给变量赋值一个命令的执行结果

v1="AAA $(ls)"

如果 v1 已经赋值,删除当前路径下的某个文件,v1 的值也不会发生变化

shell 变量、字符串的处理方法_第4张图片

        

变量的长度也是通过 ${#变量} 获取(空格也算一个字符)

shell 变量、字符串的处理方法_第5张图片

         

2. 字符串变量的高级用法

2.1. 按索引截取字符串

我们平时定义一个变量为 v='abc',在使用这个变量时通过 $ 符号 + 变量名,2种方式:

写法一:$v
写法二:${v}

这两种方式都可以,大部分人使用第1种方法(估计是为了少写两个字符),实际上标准写法是第2种。用《写法一》举1个简单的例子来看它的缺点:

目标:输出变量 v 和字符串 123 的组合

见上图,我们使用第1种方法,没有带花括号,那么被识别为变量 v123,所以出错了。如果我们带上花括号就不会出现这种情况

        

除了变量之外,我们在使用索引时,也是必须使用花括号的。语法如下:

${变量名:开始索引下标:次数}

shell 中的索引没有跳跃式匹配,只能指定索引下标和后面字符数。有两个匹配方法:

# 从左往右匹配前面字符
${v:1}
# 从右往左匹配后面字符,负数需要使用括号
${v:(-1)}

注意:索引是从0开始,所以第1个字符的下标是0,比如匹配下标为0的一个字符和下标为1的一个字符

v='abcdefghji'
echo ${v:0:1}    # 0表示从下标0开始,1表示只匹配1个字符
echo ${v:1:1}    # 前面的1表示从下标1开始,后面的1表示只匹配1个字符

字符:a b c d e f g h j i
下标:0 1 2 3 4 5 6 7 8 9

shell 变量、字符串的处理方法_第6张图片

因为只能指定索引下标的开始的次数,所以总结了以下几种方法

        

【案例一】获取第3个字符后面的全部字符

${v:2}    # 第3个字符的下标为2

        

【案例二】获取第3个字符后面的2个字符

${v:2:2}    # 第3个字符的下标为2,再指定2个字符

        

【案例三】获取最后5个字符

${v:(-5)}    # -5表示后面的5个字符
${v:(-2-3)}  # 两种方法是一样的

shell 变量、字符串的处理方法_第7张图片

        

【案例四】获取后面5个字符的前面2个

${v:(-5):2}    # -5表示后面的5个字符,2表示从左往右前2个字符

        

总结

虽然看起来方法很少,但实际上我们想要的基本都可以做到。比如:

读取前面3个字符:${v:0:2}

读取后面3个字符:${v:(-3)}

读取中间第3~5个字符:${v:2:3}

        

2.2. 按分隔符截取字符串

除了字符串常见的用法外,我们来看一下这里面的一些骚操作:先来看几个符号的解释

# :从左往右匹配第一个指定的字符,删除最前面~匹配字符
##:从右往左匹配第一个指定的字符,删除最前面~匹配字符
% :从右往左匹配第一个指定的字符,删除最后面~匹配字符
%%:从左往右匹配第一个指定的字符,删除最后面~匹配字符
* : 通配符

        

【# 例子】从左往右匹配第一个字符 / ,删除前面的值

v=/home/yt/tmp/file
${v#*/}    # 删除 / 到最前面
${v#*yt}   # 删除 yt 到最前面
${v#*m}    # 变量中有2个m,匹配模式是从左往右,所以删除的是 /hom

shell 变量、字符串的处理方法_第8张图片

这个例子对路径可能不太合适,如果是匹配文件的后缀就很好用了

v="file.txt"
${v#*.}

        

【## 例子】从右往左匹配第一个字符 / ,删除前面的值

v=/home/yt/tmp/file
${v##*/}    # 删除最后一个 / 到最前面
${v##*tmp}  # 删除 tmp 到最前面

shell 变量、字符串的处理方法_第9张图片

一个 # 号获取后缀只适用于只有一个文件名,如果存在多个点还是使用 ## 更合适

shell 变量、字符串的处理方法_第10张图片

        

【% 例子】从右往左匹配第一个字符 / ,删除后面的值

v=/home/yt/tmp/file
${v%/*}    # 删除 / 到最后面
${v%yt*}   # 删除 yt 到最后面
${v%m*}    # 变量中有2个m,匹配模式是从右往左,所以删除的是 mp/file

shell 变量、字符串的处理方法_第11张图片

        

【%% 例子】从左往右匹配第一个字符 / ,删除后面的值

v=/home/yt/tmp/file
${v%%/*}    # 删除最后一个 / 到最后面
${v%%yt*}   # 删除 yt 到最后面
${v%%m*}    # 变量中有2个m,匹配模式是从左往右,所以删除的是 me/yt/tmp/file

shell 变量、字符串的处理方法_第12张图片

        

总结

以 . 为分隔符,不显示第1列:v=192.168.20.80

  • ${v#*.}    #168.20.80

以 / 或 . 为分割符,查询路径最后一个文件名或后缀名:v=/home/yt/tmp/file.txt

  • ${v##*/}    # file.txt
  • ${v##*.}    # txt

以 / 为分隔符,显示某个文件的路径:v=/home/yt/tmp/file.txt

  • ${v%/*}    # /home/yt/tmp

以 . 为分隔符,只显示第1列:v=192.168.20.80

  • ${v%%.*}    # 192

        

2.3. 判断变量是否存在

《目录2.2》描述了通过 # 和 % 符号指定分隔符,那么还有一些其他的符号,比如冒号

【案例一】如果不存在变量或变量为空,则返回xxx(自定义输出)

${v:-'自定义输出'}

shell 变量、字符串的处理方法_第13张图片

判断变量是否为空,如果存在一个空格也不为空

shell 变量、字符串的处理方法_第14张图片

        

【案例二】如果变量不存在或为空,则指定一个默认值

${v:='默认值'}

shell 变量、字符串的处理方法_第15张图片

        

【案例三】如果变量为空则退出程序

${v:?'变量为空,退出程序'}

shell 变量、字符串的处理方法_第16张图片

        

2.4. 转换字母大小写

${v^} :转换变量v首字母为大写
${v^^}:转换变量v所有字母为大写
${v,} :转换变量v首字母为小写
${v,,}:转换变量v所有字母为小写

【案例一】转换首字母为大写、全部字母为大写

shell 变量、字符串的处理方法_第17张图片

        

【案例二】转换首字母为小写、全部字母为小写

shell 变量、字符串的处理方法_第18张图片

        

2.5. 替换字符

${变量/旧字符/新字符}

         

【案例一】将变量中 b 全部替换为 i(注意:需要两个 / 符合)

${变量//b/i}

shell 变量、字符串的处理方法_第19张图片

        

【案例二】将变量中第1个 b 替换为 i(注意:使用一个 / 符号)

${变量/b/i}

        

【案例三】将以 ab 开头的 ab 替换为 i(注意:使用 # 符号)

${变量/#ab/i}

shell 变量、字符串的处理方法_第20张图片

        

【案例四】将以 bc 结尾的 bc 替换为 i(注意:使用符号 %)

${变量/%bc/i}

shell 变量、字符串的处理方法_第21张图片

你可能感兴趣的:(shell,编程,linux,运维,shell)