一、替换操作符速查表
| 操作符 | 名称 | 作用 | 示例 | 结果 |
|---|
${var/old/new} | 替换第一个 | 替换第一次出现的old | str="a b a"; echo ${str/a/x} | x b a |
${var//old/new} | 全局替换 | 替换所有出现的old | str="a b a"; echo ${str//a/x} | x b x |
${var/#old/new} | 替换开头 | 替换开头的old | str="abc"; echo ${str/#a/x} | xbc |
${var/%old/new} | 替换结尾 | 替换结尾的old | str="abc"; echo ${str/%c/x} | abx |
二、详细示例
2.1 ${var/old/new} – 替换第一个匹配
#!/bin/bash
# 只替换第一次出现的
text="apple banana apple orange apple"
echo "${text/apple/pear}"
# 输出: pear banana apple orange apple
# ^^^^ 只替换了第一个
# 实际应用
filename="image-2024-01-15.jpg"
newfile="${filename/-/_}" # 第一个-换成_
echo "$newfile" # image_2024-01-15.jpg
2.2 ${var//old/new} – 全局替换
#!/bin/bash
# 替换所有匹配
text="apple banana apple orange apple"
echo "${text//apple/pear}"
# 输出: pear banana pear orange pear
# ^^^^ ^^^^ ^^^^ 全部替换
# 实际应用
sentence="Hello World, Hello Linux, Hello Shell"
echo "${sentence//Hello/Hi}"
# 输出: Hi World, Hi Linux, Hi Shell
# 替换空格
csv="a b c d"
echo "${csv// /,}" # a,b,c,d
2.3 ${var/#old/new} – 替换开头匹配
#!/bin/bash
# 只有开头匹配时才替换
text="abc123"
echo "${text/#abc/xyz}" # 输出: xyz123(开头匹配)
echo "${text/#123/xyz}" # 输出: abc123(开头不匹配,不变)
# 实际应用
url="https://example.com"
echo "${url/#http:/https:}" # https://example.com
# 添加前缀
path="file.txt"
echo "${path/#/data/}" # data/file.txt(在开头添加)
2.4 ${var/%old/new} – 替换结尾匹配
#!/bin/bash
# 只有结尾匹配时才替换
text="123abc"
echo "${text/%abc/xyz}" # 输出: 123xyz(结尾匹配)
echo "${text/%123/xyz}" # 输出: 123abc(结尾不匹配,不变)
# 实际应用
filename="image.jpg"
echo "${filename/%.jpg/.png}" # image.png
# 修改扩展名
for file in *.txt; do
newname="${file/%.txt/.bak}"
mv "$file" "$newname"
done
三、综合应用示例
3.1 文件批量重命名
#!/bin/bash
# rename.sh
# 将所有.jpg改为.png
for file in *.jpg; do
newname="${file/%.jpg/.png}"
echo "重命名: $file -> $newname"
# mv "$file" "$newname"
done
# 添加前缀
for file in *.txt; do
newname="backup_$file"
# 或用替换
# newname="${file/#/backup_}"
echo "新文件名: $newname"
done
# 替换文件名中的空格
for file in *\ *; do
newname="${file// /_}"
mv "$file" "$newname"
done
3.2 文本处理
#!/bin/bash
# text_process.sh
text="Hello World, Hello Shell, Hello World"
# 1. 基本替换
echo "原始: $text"
echo "替换第一个World: ${text/World/Linux}"
echo "替换所有World: ${text//World/Linux}"
echo "替换开头Hello: ${text/#Hello/Hi}"
echo "替换结尾World: ${text/%World/Everyone}"
# 2. 变量替换
name="John Doe"
echo "你好, ${name/ /, }" # 你好, John, Doe
# 3. 路径处理
path="/home/user/docs/file.txt"
echo "目录: ${path%/*}" # /home/user/docs
echo "文件名: ${path##*/}" # file.txt
echo "基础名: ${filename%.*}" # file
echo "扩展名: ${filename##*.}" # txt
3.3 数据格式化
#!/bin/bash
# format.sh
# 1. 日期格式化
date="2024-02-20"
echo "美式: ${date//-//}" # 2024/02/20
echo "日式: ${date//-//}" # 2024/02/20
echo "无分隔符: ${date//-/}" # 20240220
# 2. CSV转置
csv="a,b,c,d"
echo "CSV转空格: ${csv//,/ }" # a b c d
echo "CSV转竖线: ${csv//,/|}" # a|b|c|d
# 3. URL参数处理
query="name=John&age=25&city=NYC"
echo "${query//&/\\n}" # 每行一个参数
# name=John
# age=25
# city=NYC
# 4. 手机号格式化
phone="13800138000"
echo "${phone:0:3}-${phone:3:4}-${phone:7:4}"
# 138-0013-8000
3.4 配置文件处理
#!/bin/bash
# config.sh
# 读取配置文件
while IFS='=' read key value; do
# 去掉前后空格
key="${key// /}"
value="${value// /}"
# 替换变量引用
if [[ $value == *\${*}* ]]; then
var_name="${value#\${}"
var_name="${var_name%\}}"
value="${!var_name}"
fi
declare "$key=$value"
done < config.txt
# 模板替换
template="Hello ${name}, your home is ${home}"
content="${template//\$\{name\}/$name}"
content="${content//\$\{home\}/$home}"
echo "$content"
四、组合操作
#!/bin/bash
# complex.sh
text="Hello World, Hello Shell"
# 1. 多次替换
step1="${text//Hello/Hi}"
step2="${step1/World/Linux}"
echo "$step2" # Hi Linux, Hi Shell
# 2. 链式操作(一行)
result="${text//Hello/Hi}"
result="${result/World/Linux}"
echo "$result"
# 3. 条件替换
if [[ $text == *World* ]]; then
text="${text/World/Linux}"
fi
# 4. 变量默认值+替换
name="${1:-Guest}"
name="${name// /_}"
echo "Welcome, $name"
五、实际应用场景
5.1 日志分析
#!/bin/bash
# log_parser.sh
log="2024-02-20 10:30:25 ERROR: Connection failed"
# 提取时间
time="${log:11:8}"
echo "时间: $time"
# 提取级别
level="${log#* }"
level="${level%%:*}"
echo "级别: $level"
# 提取消息
msg="${log#*: }"
echo "消息: $msg"
# 格式化输出
formatted="${log/ / | }"
formatted="${formatted/:/ | }"
echo "$formatted"
# 2024-02-20 | 10:30:25 | ERROR | Connection failed
5.2 模板引擎
#!/bin/bash
# template.sh
name="张三"
age=25
city="北京"
template='姓名: ${name}, 年龄: ${age}, 城市: ${city}'
# 替换所有变量
result="$template"
result="${result//\$\{name\}/$name}"
result="${result//\$\{age\}/$age}"
result="${result//\$\{city\}/$city}"
echo "$result"
# 输出: 姓名: 张三, 年龄: 25, 城市: 北京
六、总结对比
| 操作符 | 作用范围 | 记忆口诀 | 常用场景 |
|---|
${var/old/new} | 第一个 | 一个斜杠 | 替换第一个 |
${var//old/new} | 全部 | 两个斜杠 | 全部替换 |
${var/#old/new} | 开头 | # 开头 | 加前缀、改开头 |
${var/%old/new} | 结尾 | % 结尾 | 改扩展名、加后缀 |
规则很简单:
/ 一个斜杠 = 第一个
// 两个斜杠 = 全部
/# 井号开头 = 匹配开头
/% 百分号 = 匹配结尾
发表回复