Skip to main content
added 711 characters in body
Source Link
Drew
  • 396
  • 1
  • 5

EditFinal edit after example added to original question:

Your second sed command with two '-e' expressions works correctly for me on the sample input provided, using Debian Jessie / sed (GNU sed) 4.2.2. (Well mostly. The last line ends up with 2 comment characters, but that shouldn't be a major issue.) Not sure if there is some variation in the way different versions of sed handle multiple expressions?

Not my preferred solution, but if you are having trouble getting sed to behave predictably with multiple expressions, you could also use tee at the end of a pipeline of individual sed commands.

sudo cat /etc/sudoers | { multiple sed commands in pipeline } | sudo tee /etc/sudoers

First edit after some clarification in the comments:

If the line that you are adding is commented out before the sed run, then the first regex is adding a second comment character to it. With two '#' characters at the beginning of the line, the second statement no longer matches and does nothing. An easy edit is to use the 1-or-more modifier on the '#' character in the second expression:

sudo sed -e 's/.*wheel/#&/' -e 's/^#\+\s*\(%wheel\s\+ALL=(ALL)\s\+NOPASSWD:\s\+LOG_INPUT:\s\+LOG_OUTPUT:\s\+ALL\)/\1/' /etc/sudoers   

Original Answer:

If I'm not mistaking your regexes, your second command is undoing the first. As a simplified example:

echo a | sed -e 's/a/b/' -e 's/b/a/'

will print a. Multiple expressions are executed in sequence for each line.

One option would be to use an alternate comment delimiter in the first step and then add a third step to sub it out. For example, instead of adding a '#' to the beginning of the line in the first expression, use 's/.*wheel/--&/'. Then after the second expression has uncommented the lines that you want, add a third -e 's/^--/#/' to clean it up.

Edit after some clarification in the comments:

If the line that you are adding is commented out before the sed run, then the first regex is adding a second comment character to it. With two '#' characters at the beginning of the line, the second statement no longer matches and does nothing. An easy edit is to use the 1-or-more modifier on the '#' character in the second expression:

sudo sed -e 's/.*wheel/#&/' -e 's/^#\+\s*\(%wheel\s\+ALL=(ALL)\s\+NOPASSWD:\s\+LOG_INPUT:\s\+LOG_OUTPUT:\s\+ALL\)/\1/' /etc/sudoers   

Original Answer:

If I'm not mistaking your regexes, your second command is undoing the first. As a simplified example:

echo a | sed -e 's/a/b/' -e 's/b/a/'

will print a. Multiple expressions are executed in sequence for each line.

One option would be to use an alternate comment delimiter in the first step and then add a third step to sub it out. For example, instead of adding a '#' to the beginning of the line in the first expression, use 's/.*wheel/--&/'. Then after the second expression has uncommented the lines that you want, add a third -e 's/^--/#/' to clean it up.

Final edit after example added to original question:

Your second sed command with two '-e' expressions works correctly for me on the sample input provided, using Debian Jessie / sed (GNU sed) 4.2.2. (Well mostly. The last line ends up with 2 comment characters, but that shouldn't be a major issue.) Not sure if there is some variation in the way different versions of sed handle multiple expressions?

Not my preferred solution, but if you are having trouble getting sed to behave predictably with multiple expressions, you could also use tee at the end of a pipeline of individual sed commands.

sudo cat /etc/sudoers | { multiple sed commands in pipeline } | sudo tee /etc/sudoers

First edit after some clarification in the comments:

If the line that you are adding is commented out before the sed run, then the first regex is adding a second comment character to it. With two '#' characters at the beginning of the line, the second statement no longer matches and does nothing. An easy edit is to use the 1-or-more modifier on the '#' character in the second expression:

sudo sed -e 's/.*wheel/#&/' -e 's/^#\+\s*\(%wheel\s\+ALL=(ALL)\s\+NOPASSWD:\s\+LOG_INPUT:\s\+LOG_OUTPUT:\s\+ALL\)/\1/' /etc/sudoers   

Original Answer:

If I'm not mistaking your regexes, your second command is undoing the first. As a simplified example:

echo a | sed -e 's/a/b/' -e 's/b/a/'

will print a. Multiple expressions are executed in sequence for each line.

One option would be to use an alternate comment delimiter in the first step and then add a third step to sub it out. For example, instead of adding a '#' to the beginning of the line in the first expression, use 's/.*wheel/--&/'. Then after the second expression has uncommented the lines that you want, add a third -e 's/^--/#/' to clean it up.

New answer
Source Link
Drew
  • 396
  • 1
  • 5

Edit after some clarification in the comments:

If the line that you are adding is commented out before the sed run, then the first regex is adding a second comment character to it. With two '#' characters at the beginning of the line, the second statement no longer matches and does nothing. An easy edit is to use the 1-or-more modifier on the '#' character in the second expression:

sudo sed -e 's/.*wheel/#&/' -e 's/^#\+\s*\(%wheel\s\+ALL=(ALL)\s\+NOPASSWD:\s\+LOG_INPUT:\s\+LOG_OUTPUT:\s\+ALL\)/\1/' /etc/sudoers   

Original Answer:

If I'm not mistaking your regexes, your second command is undoing the first. As a simplified example:

echo a | sed -e 's/a/b/' -e 's/b/a/'

will print a. Multiple expressions are executed in sequence for each line.

One option would be to use an alternate comment delimiter in the first step and then add a third step to sub it out. For example, instead of adding a '#' to the beginning of the line in the first expression, use 's/.*wheel/--&/'. Then after the second expression has uncommented the lines that you want, add a third -e 's/^--/#/' to clean it up.

If I'm not mistaking your regexes, your second command is undoing the first. As a simplified example:

echo a | sed -e 's/a/b/' -e 's/b/a/'

will print a. Multiple expressions are executed in sequence for each line.

One option would be to use an alternate comment delimiter in the first step and then add a third step to sub it out. For example, instead of adding a '#' to the beginning of the line in the first expression, use 's/.*wheel/--&/'. Then after the second expression has uncommented the lines that you want, add a third -e 's/^--/#/' to clean it up.

Edit after some clarification in the comments:

If the line that you are adding is commented out before the sed run, then the first regex is adding a second comment character to it. With two '#' characters at the beginning of the line, the second statement no longer matches and does nothing. An easy edit is to use the 1-or-more modifier on the '#' character in the second expression:

sudo sed -e 's/.*wheel/#&/' -e 's/^#\+\s*\(%wheel\s\+ALL=(ALL)\s\+NOPASSWD:\s\+LOG_INPUT:\s\+LOG_OUTPUT:\s\+ALL\)/\1/' /etc/sudoers   

Original Answer:

If I'm not mistaking your regexes, your second command is undoing the first. As a simplified example:

echo a | sed -e 's/a/b/' -e 's/b/a/'

will print a. Multiple expressions are executed in sequence for each line.

One option would be to use an alternate comment delimiter in the first step and then add a third step to sub it out. For example, instead of adding a '#' to the beginning of the line in the first expression, use 's/.*wheel/--&/'. Then after the second expression has uncommented the lines that you want, add a third -e 's/^--/#/' to clean it up.

Source Link
Drew
  • 396
  • 1
  • 5

If I'm not mistaking your regexes, your second command is undoing the first. As a simplified example:

echo a | sed -e 's/a/b/' -e 's/b/a/'

will print a. Multiple expressions are executed in sequence for each line.

One option would be to use an alternate comment delimiter in the first step and then add a third step to sub it out. For example, instead of adding a '#' to the beginning of the line in the first expression, use 's/.*wheel/--&/'. Then after the second expression has uncommented the lines that you want, add a third -e 's/^--/#/' to clean it up.