Linux – Remove lines matching string in grep

greplinux

I have some long configuration files to go through, and I would like to see just what is actually active in the .conf file, without any of the # tags. What can I use to output the lines without a # on it? I'm running Debian Wheezy with this command.

Best Answer

If the file is named foo.conf:

grep -E '^[^#].*' foo.conf should do it.

Explanation:

-E: Support extended regular expressions!

'^[^#].*': A regular expression surrounded by single quotes.

^[^#].*: The regular expression itself.

^(at position 0 of the regular expression): Says "Match starting at the beginning of a line / the first character immediately following a newline, or the first character of the file itself."

[^#]: Says "Match exactly one character that is not the character #."

.*: Says "Match zero or more of any characters except a newline, for the rest of the line."

The net effect is that, if you have a file with contents like the following:

#foo
bar
#baz
fly

This regular expression will fail to match the first and third lines, because the first character at the start of lines 1 and 3 is in fact a #, so the part of the regular expression that requires exactly one non-# ([^#]) fails to match, so grep excludes that line.

The regular expression will then succeed to match the remainder of the lines, because the first character at the start of lines 2 and 4 is indeed not a #.

Building on our success so far, you can also match lines such as:

    #I am tricky!

(Notice that there is whitespace (tabs or spaces) in front of the comment, and since it's still a comment, we don't want it!)

by using the following:

grep -P '^\s*+[^#].*' foo.conf

(but the .* is not strictly required; I know, I know.)

So now we have:

-P: Support Perl-compatible regular expressions! (Hint: may not be available universally in all versions/implementations of grep, but it at least is available for a while now in GNU Grep.)

\s*+: The little bit of added regex that says, "Match zero or more whitespace characters, meaning spaces or tabs, and if you do see them, you MUST eat them." This latter part is very important, because without the possessive quantifier *+, the space could match as part of the [^#], which would trick the regular expression. Possessive quantifiers do not exist in POSIX Compatible (Basic or Extended) regular expression flavors, so we have to use PCRE here. There may be a way to do this without a possessive quantifier, but I am not aware of it.

Related Question