echo 对字符串的删除和替换

echo 本身仅用于输出字符串,并不直接处理字符串的删除/替换;字符串的删除、替换是通过 Bash 变量参数扩展(Parameter Expansion) 实现的,echo 只是输出处理后的结果。

以下是最常用的字符串删除、替换场景,结合 echo 示例说明:

先定义测试变量

为统一示例,先定义一个基础字符串变量:

str="hello-world-hello-bash.txt"

一、字符串删除(截取/移除前缀/后缀)

核心是通过 #(删前缀)、%(删后缀)配合通配符实现,支持「最短匹配删除」和「最长匹配删除」。

语法 含义 示例 输出结果
${变量#匹配模式} 删除前缀最短匹配 echo ${str#*hello} -world-hello-bash.txt
${变量##匹配模式} 删除前缀最长匹配 echo ${str##*hello} -bash.txt
${变量%匹配模式} 删除后缀最短匹配 echo ${str%.*} hello-world-hello-bash
${变量%%匹配模式} 删除后缀最长匹配 echo ${str%%-*} hello

关键说明:

  • * 是通配符,匹配「任意长度的任意字符」;
  • # 从字符串开头匹配删除,% 从字符串结尾匹配删除;
  • 单符号(#/%)是「最短匹配」,双符号(##/%%)是「最长匹配」。

更多示例(精准删除):

# 删除前缀固定字符(无通配符)
echo ${str#hello-}  # 输出:world-hello-bash.txt

# 删除后缀固定字符
echo ${str%.txt}    # 输出:hello-world-hello-bash

# 匹配单个字符(?)
str2="a1b2c3"
echo ${str2%?}      # 删除最后1个字符 → a1b2c
echo ${str2%%?}     # 无效果(最长匹配单个字符,仅删最后1个)→ a1b2c

二、字符串替换

核心语法是 ${变量/旧字符串/新字符串},支持「单次替换」「全局替换」「开头/结尾精准替换」。

语法 含义 示例 输出结果
${变量/旧/新} 替换第一个匹配 echo ${str/hello/hi} hi-world-hello-bash.txt
${变量//旧/新} 替换所有匹配 echo ${str//hello/hi} hi-world-hi-bash.txt
${变量/#旧/新} 仅替换开头匹配 echo ${str/#hello/HELLO} HELLO-world-hello-bash.txt
${变量/%旧/新} 仅替换结尾匹配 echo ${str/%.txt/.sh} hello-world-hello-bash.sh
${变量/旧/} 删除匹配(新字符串留空) echo ${str//-/_} hello_world_hello_bash.txt
${变量//旧/} 删除所有匹配 echo ${str//hello/} -world--bash.txt

关键说明:

  • / 是替换分隔符,// 表示全局替换;
  • /# 限定「开头」匹配,/% 限定「结尾」匹配;
  • 新字符串留空(如 ${str/hello/})等价于「删除该匹配内容」。

三、扩展:大小写替换(Bash 4.0+ 支持)

除了普通替换,还可快速处理大小写:

语法 含义 示例 输出结果
${变量,,} 全部转小写 echo ${str,,} hello-world-hello-bash.txt
${变量^^} 全部转大写 echo ${str^^} HELLO-WORLD-HELLO-BASH.TXT
${变量^} 首字符转大写 echo ${str^} Hello-world-hello-bash.txt
${变量,} 首字符转小写 echo ${str^},${str,} Hello-world-hello-bash.txt,hello-world-hello-bash.txt

四、注意事项

  1. 所有操作仅临时生成新字符串,不会修改原变量(如 str 本身不变);
  2. 匹配模式支持通配符:*(任意字符)、?(单个字符)、[](字符集,如 [0-9]);
  3. 若变量未定义,扩展结果为空(如 echo ${undefined//a/b} 输出空);
  4. 分隔符可自定义(如 ${str//-/_}- 匹配,_ 替换)。

实战示例:清理字符串

# 需求:把 "  test 123@example.com  " 处理为 "test_123_example_com"
raw_str="  test 123@example.com  "
# 1. 删除首尾空格 → 2. 替换空格为_ → 3. 替换@和.为_
clean_str=${raw_str// /_}          # 替换所有空格为_ → __test_123@example.com__
clean_str=${clean_str//@/_}        # 替换@为_ → __test_123_example.com__
clean_str=${clean_str//./_}        # 替换.为_ → __test_123_example_com__
clean_str=${clean_str##*_}         # 删前缀最长_ → test_123_example_com(错误,需更精准)
# 更优雅的方式:先删首尾空格(用xargs),再替换特殊字符
clean_str=$(echo $raw_str | xargs) # 删首尾空格 → test 123@example.com
clean_str=${clean_str// /_}        # → test_123@example.com
clean_str=${clean_str//[@.]/_}     # → test_123_example_com
echo $clean_str                    # 输出:test_123_example_com