Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sed match and replace in file except for comments

Tags:

regex

bash

sed

I am trying to automatically disable logging into SSH via root. I know I can manually edit the file and do so, but I want to disable root login through a Bash script (that I use to initialize my servers).

I haven't used sed much, but I think it's what I should used based off of this question.

The line I am trying to replace, in /etc/ssh/sshd_config, is PermitRootLogin {any_value}. The default value of {any_value} is yes but I would like this to work for any value (on the same line).

I tried the command sudo sed -i "/PermitRootLogin/c\PermitRootLogin no" /etc/ssh/sshd_config but this also replaces a random comment that contains the text "PermitRootLogin".

So, I don't want to replace lines that begin with a comment token, #.

Here is the relevant parts of the file I am trying to edit (my comments are added with "###"):

# 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

The expected output is:

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

Then, I tried this: sed -i "\(^[\# ]\)+/PermitRootLogin/c\PermitRootLogin no" /etc/ssh/sshd_config.

This gives me an error of: sed: -e expression #1, char 48: unterminated address regex.

How can I accomplish what I am trying to do? Thank you!

like image 666
Rushy Panchal Avatar asked Jan 30 '26 12:01

Rushy Panchal


2 Answers

You can use this:

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

The pattern /^#/ matches a line which starts with a comment. The ! negates the match meaning the subsequent command will be executed on non-comment lines only.

The substitute comment replaces PermitRootLogin following by anything .* by PermitRootLogin no.

Use -i once you are sure it works correctly.

like image 127
hek2mgl Avatar answered Feb 01 '26 14:02

hek2mgl


Try

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

^: Beginning of line
[^#]*: any character but no #
like image 36
PhilMasteG Avatar answered Feb 01 '26 12:02

PhilMasteG



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!