shell脚本之sed使用----替换、变量、转义字符

sed替换的基本语法为:
----s后面跟的是分隔符,原字符串可使用.*这种正则表达式进行整行替换

复制代码
代码如下:
sed 's/原字符串/替换字符串/'

单引号里面,s表示替换,三根斜线中间是替换的样式,特殊字符需要使用反斜线”\”进行转义,但是单引号”‘”是没有办法用反斜线”\”转义的,这时候只要把命令中的单引号改为双引号就行了,例如:

复制代码
代码如下:
sed "s/原字符串包含'/替换字符串包含'/" //要处理的字符包含单引号

命令中的三根斜线分隔符可以换成别的符号,这在要替换的内容有较多斜线是较为方便,只需要紧跟s定义即可,例如换成问号”?”:

复制代码
代码如下:
sed 's?原字符串?替换字符串?' //自定义分隔符为问号

可以在末尾加g替换每一个匹配的关键字,否则只替换每行的第一个,例如:

复制代码
代码如下:
sed 's/原字符串/替换字符串/' //替换所有匹配关键字

上箭头”^”表示行首,美元”$”符号如果在引号中表示行尾,但是在引号外却表示末行(最后一行),这里犯二了,搜了半天哪个符号表示首行,半天才想起来,首行就是数字”1″啊.那么在行首和行尾添加字符串就是把行尾和行首替换,例如:

复制代码
代码如下:
sed 's/^/添加的头部&/g' //在所有行首添加
sed 's/$/&添加的尾部/g' //在所有行末添加
sed '2s/原字符串/替换字符串/g' //替换第2行
sed '$s/原字符串/替换字符串/g' //替换最后一行
sed '2,5s/原字符串/替换字符串/g' //替换2到5行
sed '2,$s/原字符串/替换字符串/g' //替换2到最后一行

替换样式可以多个在同一条命令中执行,用分号”;”分隔,例如:

复制代码
代码如下:
sed 's/^/添加的头部&/g;s/$/&添加的尾部/g' //同时执行两个替换规则

sed处理过的输出是直接输出到屏幕上的,要保存可以将输出重定向,或者使用参数”i”直接在文件中替换:



复制代码
代码如下:
sed -i 's/原字符串/替换字符串/g' filename //替换文件中的所有匹配项

复制代码
代码如下:
sed -i 's/原字符串/替换字符串/g' filename //替换文件中的所有匹配项

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


首先是Sed里使用变量的问题

网上有人总结了四种方案:

1.       eval sed 's/$a/$b/' filename

2.       sed "s/$a/$b/" filename

3.       .sed 's/'$a'/'$b'/' filename

4.       .sed s/$a/$b/ filename

我比较喜欢第二种,也就是:Sed后面的表达式一般用单引号引起来('),当需要使用变量时就换用双引号(")。

关于单双引号的区别:

单引号:shell处理命令时,对其中的内容不做任何处理。即此时是引号内的内容是sed命令所定义的格式。

双引号:shell处理命令时,要对其中的内容进行算术扩展。如果想让shell扩展后得到sed命令所要的格式,使用命令:sed -n "/\\\\$/p" haha,扩展后得到的结果即\\$.

 

因此对于语句类似:

$Comfilename="/home/evan/sandbox/Main/"

1. echo $Comfilename | sed 's#\/#\\\/#g'

2. echo $Comfilename | sed "s#\/#\\\/#g"

第一个的结果是:\/home\/evan\/sandbox\/Main\/

而第二个还是:/home/evan/sandbox/Main/ 因为双引号会将“\/“解释为”/“,所以sed "s#\/#\\\/#g"Shell解释成了sed s#/#\/#g sed里执行时又把”\/“转义为”/“了,这样相当于进行了了两次解释,就得不到想要的结果了。

这个例子告诉我当没必要用双引号的的时候就不要用,要不然说不定什么时候你就会很郁闷。Sed使用的变量里含有转义字符的解决当然单引号效率要比双引号高也是不要滥用双引号的原因之一。

 

言归正传,如何在sed的变量里使用那些特殊的需要转义的字符呢?

网上提出的一种方法是将sed里表示替换用的s后面的表示分隔用的字符换成别的变量里没有的字符这样就相当于变量里没有要转义的字符了。

如:

sed –i "s# $Comfilename#/Root/#" filename.list

这是一个好办法。但很不幸我需要的是删除“d”不是替换“s“。当我把同样的方法用于删除时似乎没有起到作用:sed –i "# $Comfilename#d" filename.list

 

于是只能自己手工先改写变量

$Comfilename="/home/evan/sandbox/Main/"

Tempname=` echo $Comfilename | sed 's#\/#\\\/#g'`  (这里把反单引号执行的结果给临时变量,同样的方法可以改写其他需要转义的符号。)

sed –i "# $ Tempname #d" filename.list

 

### 使用 `sed` 和 `-i` 参数直接修改文件内容 `sed` 是一种流编辑器工具,可以用来快速处理文本数据。通过使用 `-i` 参数可以直接在原文件上进行修改而无需创建临时文件。当需要替换文件中的环境变量值时,可以通过调用 shell 的 `$()` 或者 `${}` 来获取当前环境变量的值并将其嵌入到命令中。 以下是具体实现方法: #### 替换固定字符串为环境变量值 如果目标是将文件中的某个占位符替换成实际的环境变量值,则可以利用双引号 `" "` 将环境变量解析出来,并传递给 `sed` 命令[^1]。 假设有一个名为 `config.txt` 的文件,其内容如下: ``` DB_HOST=placeholder_host DB_PORT=placeholder_port ``` 现在希望将 `placeholder_host` 替换为环境变量 `HOST_VAR` 的值,以及将 `placeholder_port` 替换为环境变量 `PORT_VAR` 的值。 执行以下命令即可完成操作: ```bash sed -i "s/placeholder_host/${HOST_VAR}/g" config.txt sed -i "s/placeholder_port/${PORT_VAR}/g" config.txt ``` 上述命令会查找匹配项并将它们分别替换为目标环境变量的实际值[^2]。 #### 考虑正则表达式的特殊字符转义 某些情况下,待替换的内容可能包含正则表达式中的元字符(如 `.`, `*`, `[`, `{` 等),这可能会干扰 `sed` 的正常工作流程。因此,在编写模式串之前应确保对这些特殊字符进行了适当转义[^3]。 例如,要安全地替换路径 `/usr/local/bin` 中的部分片段至新的目录结构定义于环境变量 NEW_PATH 下面这样写更稳妥一些: ```bash escaped_path=$(printf '%s\n' "$NEW_PATH" | sed 's:[][\/.^$*]:\\&:g') sed -i "s|/usr/local/bin|$escaped_path|" somefile.conf ``` 这里先借助子shell计算得到经过必要反斜杠保护后的版本存放到变量 escaped_path 当中再参与后续动作从而避免潜在冲突风险[^4]。 #### 示例脚本综合应用 下面给出一段完整的 bash 脚本来展示如何批量更新多个配置参数对应的环境设置: ```bash #!/bin/bash # 定义需调整的目标键名数组 declare -a keys=("DB_HOST" "DB_PORT") for key in "${keys[@]}"; do value="${!key}" # 动态提取关联变量的具体数值 if [[ -n $value ]]; then sed -i "s/^${key}=.*$/${key}=${value}/" settings.ini fi done ``` 此脚本遍历预设列表里的每一个条目名称并通过间接引用机制读取对应存储的数据最后统一作用于指定格式化样式的 INI 文件之上达成自动化维护目的[^5]。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值