我正在尝试以编程方式编辑 nginx.conf 文件,其中包含如下行:
access_log /var/log/nginx/access.log;
我想看起来像这样:
access_log /dev/stdout;
我相信正则表达式^\s*access_log([^;]*);
将捕获/var/log/nginx/access.log
捕获组中的部分,但我不确定如何用 sed 正确替换捕获组?
我试过了
echo " access_log /var/log/nginx/access.log;" | sed 's/^\s*access_log([^;]*);/\1\\\/dev\\\/stdout/'
但我收到错误:
sed: -e expression #1, char 45: invalid reference \1 on `s' command's RHS
如果我尝试,sed -r
则不会出现错误,但输出不是我所期望的:
/var/log/nginx/access.log\/dev\/stdout
我试图巧妙地处理捕获组之类的东西,而不是直接搜索“access_log /var/log/nginx/access.log;”以防发行版更改默认日志文件位置。
答案1
这里有几个错误。
首先,由于sed
使用基本正则表达式,因此您需要\(
和\)
来创建一个捕获组。该-r
开关启用扩展正则表达式,这就是您不会收到错误的原因。看为什么需要转义 sed 中的正则表达式字符才能将其解释为正则表达式字符?。
其次,您将捕获组放在了错误的位置。如果我理解正确的话,你可以这样做:
sed -e 's!^\(\s*access_log\)[^;]*;!\1 /dev/stdout;!' your_file
请注意使用!
as 正则表达式分隔符以避免必须转义 中的正斜杠/dev/stdout
。
答案2
在你的正则表达式中你应该知道这\No.
是反向参考括号内的模式()
。因此正则表达式应该是's@^(\s*access_log ).*$@\1/dev/stdout/;@'
我可以提供
sed '/access_log/s|/[^;]\+|/dev/stdout|'
/
提示:无论您是否打算在模式内使用,您都可以自由更改s///
您想要的每个符号,s###
例如
答案3
与其捕获它,为什么不直接找到它并进行替换呢? IE:
sed "/access_log/ s| /.*;| /dev/stdout;|"
它搜索与“ access_log
”匹配的行,然后在任何匹配的行上将“”替换/whatever/path/is/there;
为“ /dev/stdout;
”