解决sed替换“路径”字符串的问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/sch0120/article/details/80323904

作者:史晨
创建日期:2018年05月15日
最后修改:2019年03月05日

解决方案

转义会降低可读性,只需用其他特殊字符作为sed表达式的“分隔符”(取代默认的/)即可。
例如:sed 's#CONFIG#/etc/app/config.yaml#g',使用#代替/从而避免大量转义。

你可以尝试一下echo aabbccdd | sed 's#aa#bb#g' | sed 's?bb?cc?g' | sed 's@cc@dd@g' | sed 's%dd%ee%g',可谓总有一款适合你……

这是sed命令方便用户的一个特性,vi中的:s也同样支持,灵活使用,相当方便!

更多细节

问题描述

出现问题的脚本:

user_device=/dev/nvme1n1
......
sed -i "s/^filename=.*/filename=$user_device/" ./ebs_*.fio

   
   
  • 1
  • 2
  • 3

脚本获取用户指定的块设备(一个带有/的路径),并将它写入./ebs_*.fio文件中。

执行脚本报错sed: -e expression #1, char 26: unknown option to 's',使用bash -x调试脚本发现sed命令所在行被解析为:

+ sed -i 's/^filename=.*/filename=/dev/nvme1n1/' ./ebs_ssd_randread.fio ./ebs_ssd_randwrite.fio

问题分析

我们使用sed来替换文本文件中的指定字符串,它的一般语法如下:

sed 's/oldstring/newstring/' file

如果string中包含特殊字符,则需要用\进行转义。那么脚本中的sed语句应该写为:

sed -i 's/^filename=.*/filename=\/dev\/nvme1n1/' ./ebs_*.fio

但是,脚本中的块设备是一个变量:

sed -i "s/^filename=.*/filename=$user_device/" ./ebs_*.fio

我们不便对$user_device的内容(/dev/nvme1n1)进行转义,因此变量中的/就会与sed表达式的语法冲突,从而产生错误。

看到的一种解决方法

user_device=/dev/nvme1n1
......
user_device_sed=$(echo $user_device |sed -e 's/\//\\\//g')
sed -i "s/^filename=.*/filename=${user_device_sed}/" ./ebs_*.fio

   
   
  • 1
  • 2
  • 3
  • 4

思路很简单,将路径转换成带有转义符的sed可以使用的字符串。

更好的解决方案

通过学习sed命令,我发现它有一个很好的设计,就是表达式本身的语法非常灵活。当用户不方便转义字符串中的特殊字符(如/)时,sed支持使用自定义分隔符,让用户避开冲突。

用户自定义语法的分隔符很简单,就是在s的后面紧跟自定义的分隔符即可。经过尝试,自定义的分隔符可以为%$@?#等等不会冲突的字符……大家可以简单尝试一下就可以掌握,非常方便!

echo aabbccdd | sed 's#aa#bb#g' | sed 's?bb?cc?g' | sed 's@cc@dd@g' | sed 's%dd%ee%g' 可谓总有一款适合你……

因此,只要把脚本改为下面的样子,就可以顺利执行,非常简单:

user_device=/dev/nvme1n1
......
sed -i "s#^filename=.*#filename=$user_device#" ./ebs_*.fio

   
   
  • 1
  • 2
  • 3

参考文献

  1. https://www.cnblogs.com/linux-wangkun/p/5745584.html
  2. https://blog.csdn.net/loveaborn/article/details/17269645
                                </div>
            <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-e9f16cbbc2.css" rel="stylesheet">
                </div>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值