Joel G Mathew
Joel G Mathew

Reputation: 8061

How to print a file, excluding comments and blank lines, using grep/sed?

I'd like to print out a file containing a series of comments like:

    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn
    CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
    #   SSL Engine Switch:

In essence, the file contains multiple indentation levels, where a comment starts with a # symbol.

grep should remove blank lines, and also lines where there is a hash symbol before text (implying that these are comments).

I know that blank lines can be deleted via: grep -v '^$'

However how can I delete lines with leading whitespace, and then a # symbol, and print out only lines with actual code? I would like to do this in bash, using grep and/or sed.

Upvotes: 46

Views: 82464

Answers (19)

user20059148
user20059148

Reputation:

grep -v ^$ file.txt | grep -v ^\#

First grep will remove line starting with an EOF (empty lines in English), second will remove all commented lines

Upvotes: 0

Khorem
Khorem

Reputation: 61

Here's a simple one-liner grep. This will get rid of hashes and empty lines.

grep -ve '^#' -ve '^$' /path/to/the/file

have fun.

Upvotes: 2

Fabio Lopes
Fabio Lopes

Reputation: 73

Can't think of anything simpler than:

grep -v '^ *#\|^$' filename

You can test with this file:

# comment
 # comment with space before
  # comment with two spaces before
line with text and # comment at the end

line with text

(edited to include a ' *' and handle comments with leading spaces)

Upvotes: 4

gbrener
gbrener

Reputation: 5835

With grep:

grep -v '^\s*$\|^\s*\#' temp

On OSX / BSD systems:

grep -Ev '^\s*$|^\s*\#' temp

Upvotes: 90

Ernesto Iser
Ernesto Iser

Reputation: 2634

The following:

grep -v '^#\|^$\|^\s+$' file

Would hide lines beginning with #, empty lines and lines that only contain white spaces from be printed out to the stdout. Notice that the | character has to be escaped. Hope that helps

Upvotes: 0

NeronLeVelu
NeronLeVelu

Reputation: 10039

Using default space separator

  • empty line or line with blank only have an empty $1
  • line with first non blank¨char is #, have $1 starting with #

so, keep it simple

awk '$1 ~ /^[^#]/ ' YourFile

Upvotes: 1

tamerlaha
tamerlaha

Reputation: 1990

grep ^[^#] filename
  • ^ - begin of line

  • [^#]- exclude #.

If you have spaces in the begin of line it won't work.

Upvotes: 3

user176289
user176289

Reputation: 59

sed -n '/^\s*[^#]\|^$/!'p filename

Pattern will match any amount of whitespaces (or zero) starting at the beginning of the line and following by any character that is not a #
OR empty string (nothing at all in between ^ and $).
To NOT match it, sed allows the usage of ! operator (invert match). Now pattern matches anything that regular expression don't fits in.
Thus with combination of -n (suppress of printing anything) and p flag (print) lines matching anything except the pattern will be printed.

Upvotes: 1

Mintaka
Mintaka

Reputation: 119

Little Upgrade

grep -v '^\s*$\|^#\|^\s*\#' filename

This code excludes empty lines or lines with only spaces, lines beginning with #, and lines containing nothing but spaces before #.

PS: ^# is different than ^\s*#

Upvotes: 7

Chris Koknat
Chris Koknat

Reputation: 3451

With Perl:

perl -lne 'print if ! /^\s*(#.*)?$/' file

This will also ignore C++ comments (//)

perl -lne 'print if ! m{^\s*((#|//).*)?$}' file

Upvotes: 0

Francisco Cabrera
Francisco Cabrera

Reputation: 9

grep -v '^$\|^#\|^\s*\#' filename | grep -v "^[[:space:]]*$" | more

Upvotes: 0

Francisco Cabrera
Francisco Cabrera

Reputation: 9

#!/bin/bash


#---------------------------------------------------------------#
#             Programacion Shell                                #
#             ------------------                                #
#  Programa:  xable.sh  (eXecutABLEs)                           #
###                                                           ###
#  OBJETIVO:  Filtrar solo las lineas ejecutables de un shell   #
#                                    (eXecutABLEs)              #
###                                                           ###
#  Autor...:  Francisco Eugenio Cabrera Perez                   #
#  Pais....:  Republica Dominicana                              #
#  Fecha...:  Abril 6 del 2015                                  #
#---------------------------------------------------------------#

         x_FILE=$1
if [ -z $x_FILE ];then
   echo
   echo "      $0 :  Sin Argumento^G"; echo
   echo "USO:  $0 ARCHIVO";            echo
###
   exit 1
fi
#####


#  Ignore COMMENTs and lines that...
#  ---------------------------------
#      EXPLANATION                            (PATTERN)         OBSERVATION
#      -----------                            ---------         -----------
#  1.  Begin_and_End_with_NOTHING             (^$)              NO_Characters
###
#  2.  Begin_with_HASH_symbol                 (^#)              COMMENT
#  3.  Begin_with_SPACE_and_then_HASH_symbol  (^\s*\#)          COMMENT
###
#  4.  Begin_and_End_with_SPACES              (^[[:space:]]*$)  Only_SPACES
#  -------------------------------------------------------------------------
#####
    grep -v '^$\|^#\|^\s*\#' $x_FILE | grep -v "^[[:space:]]*$" | more
#####

Upvotes: 0

jay
jay

Reputation: 1

cat filename| egrep -v "^\s*$|^;|^\s*#
  • First, cat the file
  • egrep -v removes
  • ^$ starting with empty line
  • ^; starting with ;
  • ^\s matches any leading whitespace, then any character until #

Upvotes: -1

BHG
BHG

Reputation: 1

grep -v '^$\|^#\|^\s*\#' filename

Excludes empty lines, lines beginning with # and lines containing nothing but spaces before #.

Upvotes: 0

user3155841
user3155841

Reputation: 19

egrep -v '^$|^#' /etc/sysctl.conf

Upvotes: 1

jaypal singh
jaypal singh

Reputation: 77105

With awk:

awk '!/^ *#/ && NF' file
  • !/^ *#/ - means select lines which do not have space followed by # symbol
  • NF - means select lines which are not blank
  • && - is an and operator which ensure if both of the above are true then print the line.

Upvotes: 30

captcha
captcha

Reputation: 3756

Code for GNU :

sed -r '/^(\s*#|$)/d;' file

$cat file
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    next line is empty

       line with leading space
       # line with leading space and #
    LogLevel warn
        #line with leading tab and #
        line with leading tab
    CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined
    #   SSL Engine Switch:
$sed -r '/^(\s*#|$)/d;' file
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    next line is empty
       line with leading space
    LogLevel warn
        line with leading tab
    CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined

Upvotes: 5

gniourf_gniourf
gniourf_gniourf

Reputation: 46833

This one should do:

sed 's/[[:space:]]*#.*//;/^[[:space:]]*$/d' file

On this input:

Hello everybody

# This is a comment and the previous line was empty

This is a genuine line followed by a comment # this is the comment


              # and here a comment in the middle of nowhere

you'll obtain this output:

Hello everybody
This is a genuine line followed by a comment

Caveat. This kind of method is not 100% foolproof: if you have a pound sign (#) not starting a comment, i.e., it's escaped or inside a string, well, you can imagine what will happen.

Upvotes: 4

Kevin
Kevin

Reputation: 56089

This is probably easier with sed than grep:

sed -e '/^[[:space:]]*$/d' -e '/^[[:space:]]*#/d' test.in

Or with an ERE:

# Gnu sed need -re instead of -Ee
sed -Ee '/^[[:space:]]*(#|$)/d' test.in

With the ERE, grep can do it fairly easily too:

# Not sure if Gnu grep needs -E or -r
grep -vE '^\s*(#|$)' test.in

# or a BRE
grep -v '^\s*\(#\|$\)' test.in

Upvotes: 10

Related Questions