字符串

在Bash中,变量是没有类型的,它们的值可以是任意字符串。因为变量值都是字符串,所以在Bash中进行的字符串操作都是对变量进行处理的。Bash中的字符串操作通过参数扩展来实现,也可以称为变量扩展,或者更具体地称为字符串参数扩展。 Bash中还存在其他形式的扩展详见扩展一节

另外,Bash中确实没有字符串字面量的说法,而字符串字面量在脚本中用单引号或双引号表示,本质上也是一种字符串,也可以通过参数扩展进行操作。

通过变量一节我们已经知道,变量使用${string}其简写形式是$string,字符串操作基本形式是${string},为了避免语法上冲突花括号{}不能省略

基础

${#string} 获取字符串长度

url="https://www.jartap.com"
echo ${#url} # 输出 22

${string:-default} 如果string变量已经存在并string的值非空,则返回string变量的值,否则返回default,看下面的例子:

#!/bin/bash  
  
# 设置一个非空字符串  
string="Hello"  
  
# 使用参数扩展来查看 string 的值  
echo "${string:-default}"  # 输出 "Hello",因为 string 已设置且非空  
  
# 清除 string 变量  
unset string  
  
# 再次使用参数扩展来查看 string 的值  
echo "${string:-default}"  # 输出 "default",因为 string 未设置  
  
# 使用另一个变量的值作为默认值  
another_variable="World"  
echo "${string:-$another_variable}"  # 输出 "World",因为 string 未设置

${string:=variable_value} 如果string变量已经存在并string的值非空,则返回string变量的值,否则返回default,在返回default之前,将defaultstring

#!/bin/bash  
  
string1=""  
echo "Original: ${string1}"  # 输出 "Original: "  
echo "Expanded: ${string1:-default}"  # 输出 "Expanded: default",但 string 的值仍然是空  
echo "After: ${string1}"  # 输出 "After: "
  
string2=""  
echo "Original: ${string2}"  # 输出 "Original: "  
echo "Expanded: ${string2:=default}"  # 输出 "Expanded: default",并且 string 的值被设置为 "default"  
echo "After: ${string2}"  # 输出 "After: default"

${string:+default} 如果 string 已设置并且非空,则扩展为 default,如果 string 未设置或者为空,则不进行任何扩展(即结果为空字符串)

#!/bin/bash  
  
# 设置一个非空字符串  
string="Hello"  
  
# 使用参数扩展来查看 string 的值(或 variable_value)  
echo "${string:+World}"  # 输出 "World",因为 string 已设置且非空  
  
# 清除 string 变量  
unset string  
  
# 再次使用参数扩展来查看 string 的值(或 variable_value)  
echo "${string:+World}"  # 不输出任何内容,因为 string 未设置  
  
# 使用另一个变量的值作为可能的扩展值  
another_variable="Another World"  
echo "${string:+$another_variable}"  # 如果 string 已设置且非空,则输出 another_variable 的值;否则不输出

${string:?variable_value}

#!/bin/bash  
  
string=""  
  
# 如果 string 未设置或为空,则打印 "Error: string is not set" 并退出  
echo "${string:?Error: string is not set}"  # 输出错误消息并退出脚本  
  
string="Hello"  
  
# 现在 string 已设置且非空,所以输出其值  
echo "${string:?Error: string is not set}"  # 输出 "Hello"

前缀后缀

${parameter#word} 删除前缀

它用于从变量parameter的值中删除匹配word前缀。如果word没有在parameter的值中找到匹配项,那么 ${parameter#word} 就会返回 parameter 的原始值。 其中word是模式匹配字符串(Pattern Matching), 关于模式匹配(Pattern Matching)详见这里 例如word可以是http*/,在${parameter#word}中采用最短匹配原则,匹配word,请看示例:

#!/bin/bash  
url="https://www.jartap.com/bash"  
# 使用 # 删除前缀  
prefix="https:*/"  
no_prefix="${url#$prefix}"  
echo "$no_prefix"  # 输出:/www.jartap.com/bash,最短匹配原则导致结果以 /www 开头,而不是以www开通

${parameter##word}删除前缀 同${parameter#word}一样的语法,只是采用最长匹配原则,匹配word

#!/bin/bash  
url="https://www.jartap.com/bash"  
# 使用 # 删除前缀  
prefix="https:*/"  
no_prefix="${url##$prefix}"  
echo "$no_prefix"  # 输出:bash,最长匹配原则

${parameter%word} 删除后缀 同${parameter#word}一样的逻辑,采用最短匹配原则,匹配word。只是这里删除的是后缀。

${parameter%%word}删除后缀 同${parameter##word}一样的逻辑,采用最长匹配原则,匹配word。只是这里删除的是后缀。

替换

${parameter/pattern/string}

${parameter//pattern/string}

${parameter/#pattern/string}

${parameter/%pattern/string}

转换

${parameter^pattern} ${parameter^^pattern} ${parameter,pattern} ${parameter,,pattern} ${parameter@operator}

子字符串

Bash中使用${string:position:length}提前子字符串,注意在Bash中,字符串的索引从0开始,所以${string:0:5}表示取字符串string的前5个字符。

position表示开始位置(包含这个位置的字符),可以为负数,表示从字符串末尾开始算起。为负数时候必须用()括起来,否则返回完整字符串

length表示子字符串的长度,可以为负数,表示子字符串结束位置(不包含此位置的字符),当length时候计算出来的子字符串长度小于0时,则报错。为0时候返回空字符串。

positionlength可以省略:省略position表示从字符串开头开始算起,省略length表示取到字符串末尾。

看些子字符串示例:

url="https://www.jartap.com"
echo ${url} 输出:https://www.jartap.com

echo ${url:0:5}  #输出:https
echo ${url:8}    #输出:www.jartap.com
echo ${url:8:3}  #输出:www
echo ${url::5}   #省略了position,position默认值为0,和${url:0:5}等价,输出:https 

echo ${url:1:-1} #输出:ttps://ww.jartap.co
echo ${url::-4}  #省略position,position默认为0,length为-4表示末尾第四个位置,输出:https://www.jartap
echo ${url:-4}   #输出:position的位置没有使用()括起来,所以输出:https://www.jartap
echo ${url:(-4)} #输出:.com
echo ${url:(-4):2} #输出:.c
length=2
echo ${url:(-4):$length} #输出:.co

文件路径处理

https://blog.csdn.net/astrotycoon/article/details/50814031

模式匹配

注意:模式匹配并不是正则表达式,所以不要把模式匹配和正则表达式混淆。 模式匹配(Pattern Matching)可以理解为通配符,在Bash官方文档中没有关于通配符(wildcard)说法;取而代之的是在文件名扩展章节有Pattern Matching的说明。其展现出来的意思和通配符基本相同。

?????? 模式匹配在不同场景下具有不同的意义,已知的有:

  1. 文件名扩展场景
  2. 字符串扩展场景 ??????

在模式匹配中,除了特殊字符外,其他字符均代表自身,可以使用转义符号\对特殊字符进行转义使其代表自身。比如\*代表*本身。除了使用使用\进行转义之外也可以使用''或者""包裹让其代表自身,a'*'"a*"'a*'a"*"都代表代表a*本身。

touch a'*'.data ab.data
ls -l a'*'.data # 输出: a*.data,并没有ab.data

特殊字符有:

  1. *:代表任意个字符
  2. ?:代表一个字符
  3. [...]:代表一个字符,其中[...]中的字符代表任意一个字符,[!...]表示任意一个非[...]中的字符
  4. [[:class:]]:代表一个字符,其中[:class:]代表一个字符类别,
    • [:alnum:]代表字母和数字,
    • [:alpha:]代表字母,
    • [:digit:]代表数字,
    • [:lower:]代表小写字母,
    • [:upper:]代表大写字母,
    • [:blank:]代表空格和制表符,
    • [:space:]代表空格、制表符、换行符、回车符,
    • `[:punct:],

alnum alpha ascii blank cntrl digit graph lower print punct space upper word xdigit

  1. [[:^class:]]:代表一个字符,其中[:^class:]代表一个非[:class:]中的字符
  2. \:转义字符,用于转义特殊字符,如\*表示*本身,\?表示?本身,\[表示[本身,\]表示]本身,

模式匹配的优先级:

  1. [...] > [[:class:]] > [[:^class:]] > \ > * > ?

接下来,我们看一些示例: