Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignore comments (#) using sed, but keep the lines untouched

Tags:

regex

shell

sed

I have a config file that I want to basically edit the uncommented lines, but not the commented lines. I'm using sed.

For example, I have a file called file.txt:

test
# test
# test
test

I want to replace "test" with "TEST" but do NOT touch the commented lines. Final output should show:

TEST
# test
# test
TEST
like image 671
drewrockshard Avatar asked Jan 25 '11 19:01

drewrockshard


People also ask

What is an example of ignore?

She tried to ignore him but he wouldn't leave her alone. I'll ignore that last remark. If we continue to ignore these problems they will only get worse. They ignored the warning signs.

What is a negative comment?

A negative comment is the expression of refusal or denial, a negative answer lacking any positive affirmation quality such as enthusiasm, optimism, or interests.

How do I ignore negative comments on Quora?

Turn the conversation around to the negative person and politely ask/comment on something positive e.g. 'cool shirt' or 'how is work/school going? ' Then break off politely, showing good will. There is nothing to block out, just let it roll off like harmless water and leave with an example of good manners.


2 Answers

To ignore comments that start with a # when doing a substitution, you can use the following command:

sed -r 'h;s/[^#]*//1;x;s/#.*//;(substitution command);G;s/(.*)\n/\1/' file.txt

In your case it becomes:

sed -r 'h;s/[^#]*//1;x;s/#.*//;s/test/TEST/g;G;s/(.*)\n/\1/' file.txt

The advantage of this solution over the other solutions is that it will also work if there is a comment starting later in a line, as shown in the example below. Since this solution uses the hold buffer of sed, this solution is not possible if you need to use the hold buffer for something else.

Input

test
# test
test # test
test

Output

TEST
# test
TEST # test
TEST

Explanation

  1. h; - Save in hold buffer
  2. s/[^#]*//1; - Remove everything before #
  3. x; - Swap with hold buffer
  4. s/#.*//; - Remove the comment
  5. s/test/TEST/g; - Replace all occurences of test with TEST
  6. G; - Append newline + hold buffer (the comment)
  7. s/(.*)\n/\1/ - Remove the last newline

The -r switch is required for using \1.

like image 137
user42723 Avatar answered Oct 15 '22 17:10

user42723


sed '/^#/!s/test/TEST/g' /path/to/infile

Output

$ sed '/^#/!s/test/TEST/g' infile
TEST
# test
# test
TEST

*Note: If your only requirement for a comment is that the very first non-whitespace character is a #, then you can use:

sed '/^[[:space:]]*#/!s/test/TEST/g' /path/to/infile

Output

$ sed '/^[[:space:]]*#/!s/test/TEST/g' infile
TEST
# test
 # test
TEST
like image 31
SiegeX Avatar answered Oct 15 '22 17:10

SiegeX