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 |
四、注意事项
- 所有操作仅临时生成新字符串,不会修改原变量(如
str本身不变); - 匹配模式支持通配符:
*(任意字符)、?(单个字符)、[](字符集,如[0-9]); - 若变量未定义,扩展结果为空(如
echo ${undefined//a/b}输出空); - 分隔符可自定义(如
${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