sed 在文件中匹配和替换,注释除外

Posted

技术标签:

【中文标题】sed 在文件中匹配和替换,注释除外【英文标题】:sed match and replace in file except for comments 【发布时间】:2015-11-16 13:00:52 【问题描述】:

我正在尝试自动禁用通过 root 登录 SSH。我知道我可以手动编辑文件并这样做,但我想通过 Bash 脚本(我用来初始化我的服务器)禁用 root 登录。

sed 我用的不多,但我认为基于this question,我应该使用它。

我试图在/etc/ssh/sshd_config 中替换的行是PermitRootLogin any_valueany_value 的默认值为 yes,但我希望它适用于任何值(在同一行上)。

我尝试了命令sudo sed -i "/PermitRootLogin/c\PermitRootLogin no" /etc/ssh/sshd_config,但这也替换了包含文本“PermitRootLogin”的随机评论。

所以,我不想替换以注释标记 # 开头的行。

这是我正在尝试编辑的文件的相关部分(我的 cmets 添加了“###”):

# Authentication:
LoginGraceTime 120
PermitRootLogin yes ### I want to replace this line with "PermitRootLogin no"
StrictModes yes

# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without

预期的输出是:

LoginGraceTime 120
PermitRootLogin no
StrictModes yes

# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without

然后,我尝试了这个:sed -i "\(^[\# ]\)+/PermitRootLogin/c\PermitRootLogin no" /etc/ssh/sshd_config

这给了我一个错误:sed: -e expression #1, char 48: unterminated address regex

我怎样才能完成我想做的事情?谢谢!

【问题讨论】:

...和预期的输出。 【参考方案1】:

你可以用这个:

sed '/^#/!s/PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config

模式/^#/ 匹配以注释开头的行。 ! 否定匹配,这意味着后续命令将仅在非注释行上执行。

替代评论将PermitRootLogin 替换为.* 后面的任何内容PermitRootLogin no

一旦你确定它工作正常,就使用-i

【讨论】:

我想用newword 替换除wordlist 之外的所有word,如何? 我建议发布一个问题 - 如果您找不到答案。 cmets 不是问的正确地方。 我想我的问题与这个问题类似。【参考方案2】:

试试

sed -i "s/^[^#]*PermitRootLogin .*/PermitRootLogin no/g" file

^: Beginning of line
[^#]*: any character but no #

【讨论】:

【参考方案3】:

用 GNU sed 试试这个:

sed -i 's/^PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config

【讨论】:

我认为这个应该是答案。如果PermitRootLogin 位于行首,您为什么要关心评论。顺便说一句,我认为将 .* 更改为 [^#]* 会有所帮助,因为它不会与开关一起替换尾随注释(如果有的话)。

以上是关于sed 在文件中匹配和替换,注释除外的主要内容,如果未能解决你的问题,请参考以下文章

sh 使用sed注释/取消注释配置文件中的一行,匹配模式

sed 将 // 替换为 /* */ 注释,除非// 注释出现在 /* */ 中

Shell 的sed和awk 工具

shell中的特殊符号

从补丁文件中去除 C 注释的方法

使用 sed 使所有注释保持一致