linux shell 字符串替换

%x=abcdabcd
%echo ${x/a/b} # 只替换一个
bbcdabcd
%echo ${x//a/b} # 替换所有

bbcdbbcd

举例

#test='liu.'

#echo ${test//'.'/'\.'}

liu\.


引用 参考  http://www.cnblogs.com/chengmo/archive/2010/10/02/1841355.html


在做shell批处理程序时候,经常会涉及到字符串相关操作。有很多命令语句,如:awk,sed都可以做字符串各种操作。 其实shell内置一系列操作符号,可以达到类似效果,大家知道,使用内部操作符会省略启动外部程序等时间,因此速度会非常的快。

 

一、判断读取字符串值

表达式含义
${var}变量var的值, 与$var相同
  
${var-DEFAULT}如果var没有被声明, 那么就以$DEFAULT作为其值 *
${var:-DEFAULT}如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值 *
  
${var=DEFAULT}如果var没有被声明, 那么就以$DEFAULT作为其值 *
${var:=DEFAULT}如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值 *
  
${var+OTHER}如果var声明了, 那么其值就是$OTHER, 否则就为null字符串
${var:+OTHER}如果var被设置了, 那么其值就是$OTHER, 否则就为null字符串
  
${var?ERR_MSG}如果var没被声明, 那么就打印$ERR_MSG *
${var:?ERR_MSG}如果var没被设置, 那么就打印$ERR_MSG *
  
${!varprefix*}匹配之前所有以varprefix开头进行声明的变量
${!varprefix@}匹配之前所有以varprefix开头进行声明的变量

加入了“*”  不是意思是: 当然, 如果变量var已经被设置的话, 那么其值就是$var.

[chengmo@localhost ~]$ echo ${abc-'ok'}
ok
[chengmo@localhost ~]$ echo $abc

[chengmo@localhost ~]$ echo ${abc='ok'}
ok
[chengmo@localhost ~]$ echo $abc
ok

 

如果abc 没有声明“=" 还会给abc赋值。

[chengmo@localhost ~]$ var1=11;var2=12;var3=
[chengmo@localhost ~]$ echo ${!v@}           
var1 var2 var3
[chengmo@localhost ~]$ echo ${!v*}
var1 var2 var3

 

${!varprefix*}与${!varprefix@}相似,可以通过变量名前缀字符,搜索已经定义的变量,无论是否为空值。

 

二、字符串操作(长度,读取,替换)

表达式含义
${#string}$string的长度
  
${string:position}在$string中, 从位置$position开始提取子串
${string:position:length}在$string中, 从位置$position开始提取长度为$length的子串
  
${string#substring}从变量$string的开头, 删除最短匹配$substring的子串
${string##substring}从变量$string的开头, 删除最长匹配$substring的子串
${string%substring}从变量$string的结尾, 删除最短匹配$substring的子串
${string%%substring}从变量$string的结尾, 删除最长匹配$substring的子串
  
${string/substring/replacement}使用$replacement, 来代替第一个匹配的$substring
${string//substring/replacement}使用$replacement, 代替所有匹配的$substring
${string/#substring/replacement}如果$string的前缀匹配$substring, 那么就用$replacement来代替匹配到的$substring
${string/%substring/replacement}如果$string的后缀匹配$substring, 那么就用$replacement来代替匹配到的$substring
  

说明:"* $substring”可以是一个正则表达式.

 

1.长度

[web97@salewell97 ~]$ test='I love china'
[web97@salewell97 ~]$ echo ${#test}
12

${#变量名}得到字符串长度

 

2.截取字串

[chengmo@localhost ~]$ test='I love china'
[chengmo@localhost ~]$ echo ${test:5}    
e china
[chengmo@localhost ~]$ echo ${test:5:10}
e china

${变量名:起始:长度}得到子字符串

 

3.字符串删除

[chengmo@localhost ~]$ test='c:/windows/boot.ini'
[chengmo@localhost ~]$ echo ${test#/}
c:/windows/boot.ini
[chengmo@localhost ~]$ echo ${test#*/}
windows/boot.ini
[chengmo@localhost ~]$ echo ${test##*/}
boot.ini

[chengmo@localhost ~]$ echo ${test%/*}
c:/windows
[chengmo@localhost ~]$ echo ${test%%/*}

${变量名#substring正则表达式}从字符串开头开始配备substring,删除匹配上的表达式。

${变量名%substring正则表达式}从字符串结尾开始配备substring,删除匹配上的表达式。

注意:${test##*/},${test%/*} 分别是得到文件名,或者目录地址最简单方法。

4.字符串替换

[chengmo@localhost ~]$ test='c:/windows/boot.ini'
[chengmo@localhost ~]$ echo ${test/\//\\}
c:\windows/boot.ini
[chengmo@localhost ~]$ echo ${test//\//\\}
c:\windows\boot.ini

 

${变量/查找/替换值} 一个“/”表示替换第一个,”//”表示替换所有,当查找中出现了:”/”请加转义符”\/”表示。

三、性能比较

在shell中,通过awk,sed,expr 等都可以实现,字符串上述操作。下面我们进行性能比较。

[chengmo@localhost ~]$ test='c:/windows/boot.ini'                      
[chengmo@localhost ~]$ time for i in $(seq 10000);do a=${#test};done;           

real    0m0.173s
user    0m0.139s
sys     0m0.004s

[chengmo@localhost ~]$ time for i in $(seq 10000);do a=$(expr length $test);done;      

real    0m9.734s
user    0m1.628s

 

速度相差上百倍,调用外部命令处理,与内置操作符性能相差非常大。在shell编程中,尽量用内置操作符或者函数完成。使用awk,sed类似会出现这样结果。


<think>我们之前已经讨论了Linux shell字符串替换的多种方法,包括Shell内置的参数替换、sed和awk。现在用户的具体需求是:将字符串中的特定部分替换为变量内容。这意味着替换值不是固定的字符串,而是存储在另一个变量中的值。 例如: - 有一个原始字符串:str="Hello, World!" - 有一个包含替换内容的变量:replacement="Earth" - 我们想将"World"替换为$replacement变量的值,得到"Hello, Earth!" 下面我们分别用三种方法实现这个需求,并注意替换值是一个变量(即动态内容)。 --- ### **方法1:使用Shell内置参数替换(推荐)** 在参数替换中,我们可以直接使用变量作为替换值。 **示例:** ```bash original="Hello, World!" replacement="Earth" result="${original/World/$replacement}" # 替换第一个匹配到的"World" echo "$result" # 输出:Hello, Earth! ``` **注意:** - 替换值部分直接使用`$replacement`变量,Shell会自动将其值代入。 - 如果要替换所有匹配项,使用双斜杠: ```bash original="apple apple apple" replacement="orange" result="${original//apple/$replacement}" # 替换所有"apple" echo "$result" # 输出:orange orange orange ``` --- ### **方法2:使用`sed`命令** 在`sed`中,替换值可以是一个变量,但需要注意特殊字符的转义(如`/`、`&`等)以及变量在单引号中的处理。通常,我们使用双引号来扩展变量,但双引号内需要对特殊字符进行转义。 **基本语法:** ```bash result=$(echo "$original" | sed "s/pattern/$replacement/g") ``` **示例:** ```bash original="Hello, World!" replacement="Earth" result=$(echo "$original" | sed "s/World/$replacement/") echo "$result" # 输出:Hello, Earth! ``` **重要注意事项:** 1. **变量中的特殊字符问题**:如果`replacement`变量包含特殊字符(如`/`、`&`、`\`等),会导致`sed`命令出错。我们需要在替换前对变量中的特殊字符进行转义。例如,使用`sed`的分隔符替换功能避免`/`冲突,或者使用`awk`来处理更复杂的情况。 2. **替换分隔符**:如果模式或替换值可能包含斜杠`/`,可以选择其他字符作为分隔符,例如`|`、`:`、`#`等: ```bash original="Path: /usr/local/bin" replacement="/opt/bin" # 使用|作为分隔符,避免转义/ result=$(echo "$original" | sed "s|/usr/local/bin|$replacement|") echo "$result" # 输出:Path: /opt/bin ``` 3. **全局替换**:添加`g`标志进行全局替换: ```bash original="apple apple apple" replacement="orange" result=$(echo "$original" | sed "s/apple/$replacement/g") echo "$result" # 输出:orange orange orange ``` **转义特殊字符的函数(可选):** 如果替换值可能包含特殊字符(如`/`、`&`、`\`等),我们可以先转义这些字符: ```bash # 定义一个函数来转义sed替换字符串中的特殊字符(仅转义&、/、\等) escape_sed_replacement() { echo "$1" | sed -e 's/[&/\]/\\&/g' } replacement_safe=$(escape_sed_replacement "$replacement") result=$(echo "$original" | sed "s/pattern/$replacement_safe/g") ``` --- ### **方法3:使用`awk`命令** `awk`的`gsub`函数可以接受变量作为替换值,并且对特殊字符的处理相对更安全。 **示例:** ```bash original="Hello, World!" replacement="Earth" result=$(echo "$original" | awk -v rep="$replacement" '{ gsub(/World/, rep); print }') echo "$result" # 输出:Hello, Earth! ``` **说明:** - 使用`-v`选项将Shell变量`replacement`赋值给`awk`变量`rep`。 - 在`awk`脚本中,使用`gsub`函数进行全局替换(如果只想替换第一个匹配项,使用`sub`函数代替`gsub`)。 - `awk`处理特殊字符的能力比`sed`强,但依然需要注意正则表达式的特殊字符(如`.`、`*`、`[`等)。如果模式中包含这些字符,需要进行转义(例如,使用`gsub(/\./, rep)`来替换点号)。 --- ### **总结** | 方法 | 优点 | 缺点 | 适用场景 | |------------------------|-------------------------------------------|--------------------------------------------|----------------------------------------| | Shell内置参数替换 | 简单高效,无需外部命令 | 模式匹配不支持完整正则表达式 | 简单的变量替换,且替换值无特殊字符 | | `sed` | 支持正则表达式,灵活 | 替换值中的特殊字符需要转义 | 复杂模式匹配,替换次数控制(如全局替换)| | `awk` | 强大的文本处理能力,变量传递方便 | 语法相对复杂 | 需要基于列处理或替换值有特殊字符的情况 | **通用建议:** - 对于简单的替换,优先使用Shell内置参数替换。 - 当替换值包含特殊字符时,考虑使用`awk`避免转义问题。 - 如果需要进行复杂的模式匹配(如正则表达式),使用`sed`或`awk`。 --- ### **相关问题** 1. 如何在Shell脚本中安全地处理包含特殊字符的替换值? 2. 使用`sed`进行字符串替换时,如何避免替换值中的斜杠`/`导致语法错误? 3. 在`awk`中如何仅替换字符串中第N次出现的匹配项? --- 以上内容解决了用户提出的“将字符串替换为变量内容”的需求,并考虑了替换值作为变量的特殊注意事项。如有进一步问题,欢迎继续探讨! </think>在 Linux shell 中,将字符串替换为变量内容主要涉及 **变量嵌套** 和 **动态替换** 技术。以下是三种常用方法(均支持替换值为变量): --- ### 方法 1:Shell 内置参数替换(推荐) 使用 `${var/pattern/$replacement_var}` 格式,直接嵌套变量: ```bash original="Hello NAME" replacement_var="Alice" result="${original/NAME/$replacement_var}" # 替换 NAME→Alice echo "$result" # 输出:Hello Alice ``` 全局替换(所有匹配项): ```bash original="apple orange apple" repl="banana" result="${original//apple/$repl}" # 双斜杠表示全局替换 echo "$result" # 输出:banana orange banana ``` **优点**:无需外部命令,执行效率最高[^2]。 --- ### 方法 2:使用 `sed` 命令 通过双引号解析变量,用 `"s/pattern/$var/"` 格式: ```bash str="File: path/to/file" new_path="/opt/data" result=$(echo "$str" | sed "s|path/to/file|$new_path|") # 使用 | 避免 / 冲突 echo "$result" # 输出:File: /opt/data ``` **注意事项**: 1. 必须使用 **双引号** `"` 允许变量扩展 2. 若替换值含特殊字符(如 `/`),需改用其他分隔符(如 `|`, `:`)[^3] --- ### 方法 3:使用 `awk` 命令 通过 `-v` 传递变量值: ```bash text="Version: X.X.X" version="2.0" result=$(echo "$text" | awk -v repl="$version" '{gsub(/X\.X\.X/, repl); print}') echo "$result" # 输出:Version: 2.0 ``` **优点**:支持复杂逻辑和处理特殊字符[^1]。 --- ### 三种方法对比 | **方法** | 执行效率 | 特殊字符处理 | 适用场景 | |----------------|----------|--------------|------------------------------| | Shell 内置替换 | ⭐⭐⭐⭐️ | ⭐⭐️ | 简单变量替换,无特殊字符 | | `sed` | ⭐⭐️⭐️ | ⭐⭐⭐ | 需正则匹配或替换文件内容 | | `awk` | ⭐⭐️ | ⭐⭐⭐⭐️ | 含特殊字符或需复杂逻辑的场景 | > **特殊字符处理示例**(替换含 `/` 的路径): > ```bash > # 使用sed的分隔符避免冲突 > path_str="PATH=/old/bin" > new_dir="/usr/new/bin" > echo "$path_str" | sed "s|/old/bin|$new_dir|" > ``` --- ### 关键注意事项 1. **变量作用域**:确保替换变量已定义 2. **引号规则**: - 单引号 `'`:禁用变量扩展(不可用) - 双引号 `"`:允许变量扩展(必须使用) 3. **特殊字符转义**: - 内置替换:直接支持普通字符 - `sed`/`awk`:对 `$`、`\` 等需用 `\\` 转义 --- ### 相关问题 1. 如何在 Shell 参数替换中处理含有空格或特殊字符的替换值? 2. 使用 `sed` 进行变量替换时,如何避免命令注入安全风险? 3. 如何实现多层嵌套变量的字符串替换(如 `${var1/$var2/$var3}`)?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值