解决脚本实现:sed -i 替换变量,变量中含有特殊转义字符的问题

简介: 解决脚本实现:sed -i 替换变量,变量中含有特殊转义字符的问题

写脚本时遇到的一个问题,在此分享一下


首先我利用awk命令取出某文件中的一个字段,并赋给了一个变量aaa,awk命令如下:

aaa=` awk '{if($0~"inst.stage2=hd")print}' ~/test`

此句我是以“inst.stage2=hd”为参考,在~/test文件中,找出匹配的字段


(awk命令不做详细解释,具体可以参考:https://www.runoob.com/linux/linux-comm-awk.html


awk命令运行后查找字段结果如下:


1.png


我直接利用sed -i ‘s/原字符/替换后字符/g’  命令对awk查找出来的字段进行修改,会出现错误


1.png


出现错误的原因是sed ‘s///g’ 中间填入的原字符和替换字符处,特殊字符必须转义,上图中的/dev/sda1 的两个“/”没有转义


正确语句应为

sed -i "s/inst.stage2=hd:LABEL=\/dev\/sda1/inst.stage2=hd:LABEL=KYLIN-BACKUP/g" ~/test  (1-1)

1.png


也就是\/dev\/sda1 , “\”为转义字符,是不同于目录的字符,要注意分清


上面的部分只是简单的用awk命令加上sed命令在命令行中进行简单的查找和替换,但如果我的awk查找命令,将结果赋给了一个变量aaa,如果直接使用做替换

sed -i "s/$aaa/inst.stage2=hd:LABEL=KYLIN-BACKUP/g" ~/test

结果不会报错,但是发现test文件并没有按要求进行修改,相关字段仍为【inst.stage2=hd:LABEL=/dev/sda1】


原因:


此时字段通过aaa变量获取,但仍存在字符转义问题,需要对aaa这个变量稍加修改,使sed 运行时得到的结果为带有转义字符,如语句(1-1)所示


解决:


我将变量aaa的内容赋给了第二个变量,取名为a,将里面的“/”都替换为“\/” ,代码如下

a=` echo $aaa | sed 's#\/#\\\/#g'`

解释一下 ,此处的sed 框架是用的  sed 's#原字符#替换后字符#g' ,此时以“#”作为分隔符,为了不与目录的分隔符起冲突,作用其实一样


1.png


这里一共六个\ / 这样的字符我们暂时称为【字符1-6】,下面分别解释一下都是什么意思 (手写数字难看,大家忽略~)


1、转义字符“\” (在回车的上面),是为了将【字符2】的 “ / ” 进行转义;


2、原本字符 “ / ”,表示目录的意思,是被【字符1】转义的字符,【字符1】与【字符2】组合在一起  “ \ / ” 放在sed的第一组# #内,对照【sed 's#原字符#替换后字符#g' 】,也就是匹配原句中的两个 “ / ”


1.png


3/4/5/6、 想要达到的效果是,替换后的字符变成 “ \ / ” ,但是这两个字符又都是特殊字符,需要转义,将 \ 转义后是 \\  ,将 / 转义后是\ / ,  所以连起来就是 \\\/


综上,最后将三个语句连起来,写入脚本

#!/bin/sh
aaa=` awk '{if($0~"inst.stage2=hd")print}' ~/test`
a=` echo $aaa | sed 's#\/#\\\/#g'`
sed -i "s/$a/inst.stage2=hd:LABEL=KYLIN-BACKUP/g" ~/test

第一行是awk取到对应字段


第二行是将取到内容中含有 “ / ” 的字符 都替换为“ \ / ”


第三行是将含有转义字符的变量a,替换成【inst.stage2=hd:LABEL=KYLIN-BACKUP】并写入~/test中(sed -i ,-i这个参数,不加就是不写入,但可以看结果,加 i 就是直接写入到原文件)


结果:


替换前文件内容:


1.png


执行脚本后文件内容:


1.png


END


相关文章
|
Shell
shell中并发执行多个进程
shell中并发执行多个进程
1441 4
|
Shell
Shell 字符串操作(截取、替换、去头、去尾)
Shell 字符串操作(截取、替换、去头、去尾)
1154 0
|
Kubernetes 网络协议 关系型数据库
Kubernetes----ExternalName类型的Service
Kubernetes----ExternalName类型的Service
2690 0
|
开发者 Docker 容器
DockerFile的ADD和COPY的区别
DockerFile的ADD和COPY的区别
4805 0
|
Ubuntu 开发工具 Python
Ubuntu apt-get和pip国内源更换
Ubuntu apt-get和pip源更换 更新数据源为国内,是为了加速安装包的增加速度。 更换apt-get数据源 输入:sudo -s切换为root超级管理员; 执行命令:vim /etc/apt/sources.
13374 0
|
Shell Perl
用sed如果原字符串或新字符串中包含特殊字符(如正斜杠/或其他特殊字符),需要用\进行转义
用sed如果原字符串或新字符串中包含特殊字符(如正斜杠/或其他特殊字符),需要用\进行转义
1589 7
|
jenkins 持续交付
Jenkins Pipeline 流水线 - Parameters 参数化构建
Jenkins Pipeline 流水线 - Parameters 参数化构建
509 0
|
Unix
深入理解 CMake 的 `cmake --build` 命令
深入理解 CMake 的 `cmake --build` 命令
2049 1
|
缓存 Prometheus 监控
【Prometheus+Grafana系列】基于docker-compose搭建
本文主要介绍prometheus和grafana的基本功能,并使用docker-compose方式搭建了样例环境。
|
网络协议 Linux
Cannot assign requested address解决办法
Cannot assign requested address解决办法