Pregunta

I want to remove 1st character on file when grep some string. But need that changed row to be on the same position before the edit.

Example file:

#%PAM-1.0
auth            sufficient      pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
#auth           sufficient      pam_wheel.so trust use_uid
auth            include         system-auth
account         sufficient      pam_succeed_if.so uid = 0 use_uid quiet

Expected View after the edit:

#%PAM-1.0
auth            sufficient      pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
auth           sufficient      pam_wheel.so trust use_uid
auth            include         system-auth
account         sufficient      pam_succeed_if.so uid = 0 use_uid quiet

In that case on 4th row need just to remove "#", but I want to do that when search the string "sufficient pam_wheel.so trust use_uid" not when point the exact row that I want to edit.

¿Fue útil?

Solución

This is a job for sed:

$ sed -r 's/^#(.*sufficient\s+pam_wheel\.so trust use_uid.*)/\1/' file
#%PAM-1.0
auth            sufficient      pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
auth           sufficient      pam_wheel.so trust use_uid
auth            include         system-auth
account         sufficient      pam_succeed_if.so uid = 0 use_uid quiet

Regexplanation:

s/                            # Substitute  
^#                            # A line starting with a #
(                             # Start capture group
.*                            # Followed by anything
sufficient                    # Followed by the word sufficient
\s+                           # Followed by whitespace
pam_wheel\.so trust use_uid   # Followed by the literal string (escaped .)
.*                            # Followed by anything
)                             # Stop capture group
/                             # Replace with 
\1                            # The first capture group 

So effectively we are matching lines starting with # containing the string sufficient\s+pam_wheel.so trust use_uid and removing the #

Notes: the -r flag is for extended regexp, it might be -E for your version of sed so check the man.

If you want to store the changes back to the file use the -i option:

$ sed -ri 's/^#(.*sufficient\s+pam_wheel\.so trust use_uid.*)/\1/' file

If the column aligment is important then capture up to sufficient and after it so you get 2 capture groups and replace with \1 \2.

$ sed -r 's/^#(.*)(sufficient\s+pam_wheel\.so trust use_uid.*)/\1 \2/' file
#%PAM-1.0
auth            sufficient      pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
auth            sufficient      pam_wheel.so trust use_uid
auth            include         system-auth
account         sufficient      pam_succeed_if.so uid = 0 use_uid quiet

Edit:

Replace the string AllowUsers support admin with #AllowUsers support admin:

$ sed -r 's/^(AllowUsers support admin.*)/#\1/' file
#AllowUsers support admin

$ sed -r 's/^(DeniedUsers root.*)/#\1/' file
#DeniedUsers root

Otros consejos

perl -pi -e '$_=~s/^.//g if(/sufficient      pam_wheel.so trust use_uid/)' your_file

Note: This would do inplace replacement.so after you run the command your file will be modified automatically.

Here's one way using sed:

sed '/sufficient \+pam_wheel.so \+trust \+use_uid/s/^#//' file

Results:

#%PAM-1.0
auth            sufficient      pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
auth           sufficient      pam_wheel.so trust use_uid
auth            include         system-auth
account         sufficient      pam_succeed_if.so uid = 0 use_uid quiet

Using awk you can do:

awk -F '#' '{ if ($0 ~ /^#.*sufficient +pam_wheel.so trust use_uid/) {$1=""; print;} else print}'  infile

OR (if there can be only one # at the start):

awk -F '#' '{ if ($0 ~ /^#.*sufficient +pam_wheel.so trust use_uid/) print $2; else print}'  infile

sed commands can only do RE matches not string comparisons so to use sed you'd need to parse your desired string to escape all RE metacharacters which is error-prone (e.g. the currently posted solutions all neglect to escape the "." in pam_wheel.so).

Better to just do a string comparison when you're trying to match a string, e.g.:

awk 'index($0,"sufficient pam_wheel.so trust use_uid"){sub/^#/,"")}1' file > tmp && mv tmp file
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top