Sed替换bash中的非注释行

时间:2016-06-20 14:37:30

标签: bash sed rc

我觉得我已经接近解决这个问题,但却无法实现这一目标。

我有一个脚本,用于搜索/etc/rc.local中是否调用了一个实用程序。如果它不是,我想在文件末尾的exit 0之前添加一行调用它。到目前为止,我有这个:

sudo sed -i 's/.*exit 0.*/'$UTILITY_PATH'\n&/' /etc/rc.local

这种作品,但也匹配"退出0"作为评论 - 进一步发生/etc/rc.local,提醒用户确保脚本以此行结束。

因此,要明确,以下内容应该匹配:

exit 0
 exit 0
exit   0   

等等。以下内容不匹配:

#exit 0
#     exit 0
#   blah blah "exit 0" blah blah
# exit    0

有人能指出我正确的方向吗?

3 个答案:

答案 0 :(得分:2)

我想你想要这个:

sed -r -i 's/^\s*exit\s{1,}[0-9]/foo\n&/' /etc/rc.local

匹配exit [0-9] - 前面和中间可能有空格。

顺便说一句,你也可以同时执行这两项搜索,如果找到了模式,可以使用awk一步完成插入:

awk '/foo/{m=1}/^\s*exit\s+[[:digit:]]/&&!m{print "foo"}1' /etc/rc.local

较新版本的GNU awk也支持就地编辑:

awk -i inplace '/foo/{m=1}/^\s*exit\s+[[:digit:]]/&&!m{print "foo"}1' /etc/rc.local

答案 1 :(得分:2)

这是关于regular expressions的问题,对吗?你想要的是exit 0的匹配,除非前面有#。那怎么样?

sudo sed -i 's/^[^#]*exit 0.*/'$UTILITY_PATH'\n&/' /etc/rc.local

答案 2 :(得分:0)

你在车道中间有'#'吗? bcaus如果'#'是第一个可打印的角色你很容易找到: 再使用一个正则表达式(这里非常简单)确定sed操作的范围就像这样:

sed '/^\W*#/ ! s/something_u_want/whatever_u_want/ ' /etc/rc.local

/^\W*#/表示sed仅适用于此注册表的行,否则不会执行任何操作 并且感叹只是否定所以条件反转 - 现在sed将仅适用于那些从'#'开始的行

如果#不是先...那么......嗯...也许:

sed '/^[^#]*exit 0/ s/something_u_want/whatever_u_want/ ' /etc/rc.local