如何编写sed命令:不存在指定字符串则追加,存在则忽略
需求:编写sed命令处理特定日志配置行
原始行与目标行
原始行示例:
*.info;mail.none;authpriv.none;cron.none /var/log/messages
需要替换为:
*.info;mail.none;authpriv.none;cron.none;local2.none;local5.none /var/log/messages
处理条件
- cron.none与
/var/log/messages之间的空格数量不固定 - 若行中已存在
;local2.none;local5.none,跳过追加操作 - 即使行中有
local6.none但无目标字符串,仍需追加;local2.none;local5.none
尝试过的无效命令
sed -i -e "/*.info;mail.none;authpriv.none;cron.none;local2.none;local5.none.*\+\/var\/log\/messages/! /*.info;mail.none;authpriv.none;cron.none.*\+\/var\/log\/messages/ s/cron.none/cron.none;local2.none;local5.none/g" $SYSLOGCONFFILE
sed -i -e "/*.info;mail.none;authpriv.none;cron.none.*\+\/var\/log\/messages/.*local2.none;local5.none.*/!s/cron.none/cron.none;local2.none;local5.none/g" $SYSLOGCONFFILE
sed -i -e "/*.info;mail.none;authpriv.none;cron.none;local2.none;local5.none.*\+\/var\/log\/messages/! /*.info;mail.none;authpriv.none;cron.none.*\+\/var\/log\/messages/ s/cron.none/cron.none;local2.none;local5.none/g" $SYSLOGCONFFILE
解决方案
正确的sed命令
sed -i '/local2.none;local5.none/! s/\(cron.none\)\(\s*\/var\/log\/messages\)/\1;local2.none;local5.none\2/' "$SYSLOGCONFFILE"
命令解释
- 跳过已匹配行:
/local2.none;local5.none/!仅对不包含目标字符串的行执行后续替换 - 精准捕获替换:
\(cron.none\)捕获cron.none作为第一个分组\(\s*\/var\/log\/messages\)捕获cron.none到日志路径之间的所有空格和路径本身作为第二个分组- 替换时在
cron.none后追加目标字符串,保留原有的空格和路径结构
原命令失效原因
- 使用了错误的sed地址匹配语法:sed的模式匹配直接用
/pattern/,无需额外包裹* - 未启用扩展正则时,
\+会被当作普通字符处理,无法实现匹配1个以上字符的效果 - 条件判断结构错误,sed的条件执行需遵循
/pattern/! command的格式,而非多个地址拼接
内容的提问来源于stack exchange,提问作者divakar reddy
相关产品推荐
相关产品推荐

