Sed 替换 bash 中的非注释行

Sed replace non-commented lines in bash

我觉得我快要解决这个问题了,但还不能完全解决。

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

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

这种方法有效,但也匹配带有 "exit 0" 的行作为注释 - 进一步出现 /etc/rc.local 以提醒用户确保脚本应以此行结尾。

所以,为了清楚起见,以下内容应该匹配:

exit 0
 exit 0
exit   0   

等等。以下不应匹配:

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

任何人都可以指出正确的方向吗?

我猜你想要这个:

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

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


顺便说一句,您还可以执行两者,如果找到模式则进行搜索,并且可以使用 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

这是关于 regular expressions 的问题,对吧?你想要的是 exit 0 的匹配,除非它前面有 #。这个呢?

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

你在车道中间有'#'吗? 因为如果 '#' 是第一个可打印字符,那么您就处于非常容易的位置: 再使用一个正则表达式(这里非常简单)来确定 sed 操作的范围,就像这样:

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

/^\W*#/ 表示 sed 将仅适用于对这个正则表达式进行数学运算的行,否则什么都不做
感叹号只是否定,所以条件是相反的——现在 sed 将只适用于这些不从 '#'

开始的行

if # isnt first then...嗯...也许:

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