shell字符串替换

案例,将所有文件名前面的“old_”字符串删除,新文件名格式为/a1/deployment-ingress.yaml

/a1/old_deployment-ingress.yaml
/b1/b2/old_deployment-ingress.yaml
/b1/old_deployment-ingress.yaml
/c1/c2/c3/old_deployment-ingress.yaml
/c1/c2/c3/old_2-deployment-ingress.yaml
/c1/c2/old_deployment-ingress.yaml
/c1/old_deployment-ingress.yaml
#! /bin/bash

for file in $(find . -maxdepth 5 -name "old*.yaml"); do
    mv $file ${file/old_/}
done

这种方法是 Bash(Bourne Again SHell)脚本中的字符串替换操作。

在你的脚本中,字符串替换操作是通过 ${variable/pattern/replacement} 语法实现的。这个结构表示对 variable 变量的值进行处理,查找 pattern 模式,并用 replacement 替换它。如果 replacement 部分为空,那么匹配到的 pattern 就会被删除。

具体到你的脚本:

${file} 是当前遍历到的文件路径。 old_ 是要在文件名中查找并替换的模式(pattern)。 替换(replacement)部分为空,所以 old_ 被删除。 Bash 的这种字符串替换功能非常强大,它允许你在不启动外部程序(如 sed 或 awk)的情况下快速修改字符串,特别适合用于简单的脚本任务,如批量重命名文件。


在 Bash shell 中,除了 ${variable/pattern/replacement} 这种字符串替换操作,还有许多其他类似的操作来处理字符串。这些操作是 Bash 的参数展开(Parameter Expansion)的一部分,它们提供了丰富的功能来修改和操作字符串。以下是一些常用的操作:

  1. 字符串长度:

    • ${#variable}: 返回 variable 中的字符数。

  2. 子字符串提取:

    • ${variable:position}: 从 variable 中提取子字符串,开始于索引 position(基于 0 的索引)。

    • ${variable:position:length}: 从 variable 中提取长度为 length 的子字符串,开始于索引 position

  3. 字符串删除:

    • ${variable#pattern}: 删除 variable 前面最短匹配 pattern 的部分。

    • ${variable##pattern}: 删除 variable 前面最长匹配 pattern 的部分。

    • ${variable%pattern}: 删除 variable 后面最短匹配 pattern 的部分。

    • ${variable%%pattern}: 删除 variable 后面最长匹配 pattern 的部分。

  4. 默认值:

    • ${variable:-default}: 如果 variable 未设置或为空,则使用 default

    • ${variable:=default}: 如果 variable 未设置或为空,则设置 variabledefault 并使用该值。

    • ${variable:+alternative}: 如果 variable 被设置且非空,则使用 alternative,否则返回空字符串。

  5. 大小写转换:

    • ${variable,,}: 将 variable 中的所有字母转换为小写。

    • ${variable^^}: 将 variable 中的所有字母转换为大写。

    • ${variable,}: 只将 variable 的第一个字母转换为小写。

    • ${variable^}: 只将 variable 的第一个字母转换为大写。

这些操作使 Bash 脚本能够在不借助外部工具如 sedawk 的情况下进行复杂的字符串处理。通过结合使用这些操作,你可以构建出功能强大的字符串处理逻辑。


子字符串提取

在 Bash 中进行子字符串提取时,索引是按照每个字符来计算的。字符串的第一个字符的索引为 0,依此类推。这个索引机制用于指定从哪里开始提取子字符串,以及要提取多长的子字符串。

  1. ${variable:position}: 这个表达式从 variableposition 索引处开始,提取直到字符串末尾的子字符串。例如,如果 variable="HelloWorld",那么 ${variable:3} 将返回 "loWorld"。

  2. ${variable:position:length}: 这个表达式从 variableposition 索引处开始,提取长度为 length 的子字符串。继续上面的例子,如果 variable="HelloWorld",那么 ${variable:3:4} 将返回 "loWo"。

这里有几点需要注意:

  • 索引是从 0 开始的。所以,第一个字符的索引是 0,第二个字符的索引是 1,依此类推。

  • 如果 position 是负数,它将从字符串的末尾开始计数,但必须使用空格与冒号隔开,比如 ${variable: -3}

  • 如果 length 超过了字符串的实际长度,剩余的字符串将被完整提取,不会产生错误或截断。

  • 如果 length 被省略,子字符串将从 position 开始,一直提取到字符串的末尾。


最长匹配、最短匹配

在 Bash 中进行字符串删除操作时,"最长匹配"(Longest Match)和"最短匹配"(Shortest Match)的概念是用来确定在使用模式(pattern)匹配时,应该删除字符串中的哪一部分。这些操作是 Bash 字符串处理的强大特性之一,允许你以灵活的方式处理字符串。让我们分别了解一下这两种匹配模式:

最短匹配

  • ${variable#pattern}: 删除从字符串开始到第一次出现 pattern 匹配的部分(即最短匹配)。它只删除匹配模式的最短可能部分。

例如,假设 variable="start-middle-end",那么:

  • 如果使用 ${variable#*-},则 pattern*-(匹配任何东西后跟一个连字符)。最短匹配删除到第一个连字符,因此返回 "middle-end"

最长匹配

  • ${variable##pattern}: 删除从字符串开始到最后一次出现 pattern 匹配的部分(即最长匹配)。它删除匹配模式的最长可能部分。

同样的例子,variable="start-middle-end"

  • 使用 ${variable##*-} 时,pattern 仍然是 *-。最长匹配删除到最后一个连字符,因此返回 "end"

总结和比较

  • 最短匹配(#)找到的是满足模式的最短的部分,而最长匹配(##)则找到满足模式的最长的部分。

  • 对于字符串尾部的匹配,有对应的 %(最短匹配)和 %%(最长匹配)操作,它们的工作原理类似,但是从字符串的尾部开始匹配。


关于 Shell 参数传递 与 默认值

shell 给变量定义默认值,或当变量为空时为变量赋一个默认值

a=$1
var=${a:-"string"}	# 变量a为null或为空字符串的时候,则var的值为"string",这里可以接变量或字符串
echo $var

将上面的命令写入一个test.sh文件,运行时,如果test.sh后面不接任何内容,则输出"string",否则输出变量a的值

与之相反的是

a=$1
var=${a:+"string"}	# 变量a不为空时,则var的值为"string"
echo $var

总共有以下几种情况 - 变量为null,则变量为-后面的值 :- 变量为null 或为空字符串时,则变量为-后面的值 :+变量不为空时使用默认值,跟:-相反 = 变量为null时,同时改变变量值,例如 变量a为null,var=${a="string"},则变量var和a的值都是"string" := 变量为null 或 空字符串, 同时改变变量值,例如 变量a为null或变量a为空字符,var=${a:="string"},则变量var和a的值都是"string" :?变量为null 或 空字符串时报错并退出

最后更新于