sed - Commenting a line matching a specific string AND that is not already commented out

Assuming you don't have any lines with multiple #s this would work:

sed -e '/BBB/ s/^#*/#/' -i file

Note: you don't need /g since you are doing at most one substitution per line.


I find this solution to work the best.

sed -i '/^[^#]/ s/\(^.*BBB.*$\)/#\ \1/' file

It doesn't matter how many "#" symbols there are, it will never add another one. If the pattern you're searching for does not include a "#" it will add it to the beginning of the line, and it will also add a trailing space.

If you don't want a trailing space

sed -i '/^[^#]/ s/\(^.*BBB.*$\)/#\1/' file

Another solution with the & special character which references the whole matched portion of the pattern space. It's a bit simpler/cleaner than capturing and referencing a regexp group.

sed -i 's/^[^#]*BBB/#&/' file

Assuming the BBB is at the beginning of a line, I ended up using an even simpler expression:

sed -e '/^BBB/s/^/#/' -i file

One more note for the future me. Do not overlook the -i. Because this won't work: sed -e "..." same_file > same_file.