2009-07-15

Searching files with grep

It is pretty common that you might want to search for text within a file or directory. The best way to do that is with grep. The basic way to use grep is:

$ grep [PATTERN] [FILE]

  • Searching a single file
    A simple example would be if you wanted to see all the different Linux kernels that show up in your /boot/grub/menu.lst file, you could:

    $ grep kernel /boot/grub/menu.lst

  • Searching for multiple strings
    What if you want to search for multiple strings in one file? Say, you want to see all the section headings, identifiers, and drivers in your /etc/X11/xorg.conf file. You could do this by using the -e option, and I'll also use the -i option to ignore case when searching:

    $ grep -i -e section -e identifier -e driver /etc/X11/xorg.conf

  • Searching multiple files
    It is also possible to use grep on all the files in a directory or just on a couple files that you want using either the * wildcard or by identifying files with the -f option. For example, let's say I wanted to search all my blog posts saved on my computer for ones that mention ImageMagick:

    $ grep -i imagemagick ~/blog/*

  • Displaying lines before and/or after match
    Sometimes you want to see the context in which the matched text appears. To do this we can use the following options: -A, for lines after the match; -B, for lines before the match; or -C, for lines on both sides of match. So, repeating the previous ImageMagick search to display 5 lines of text after the match, 5 lines before the match, or 5 lines on both sides of the match, we could use the following, respectively:

    $ grep -iA 5 imagemagick ~/blog/*
    $ grep -iB 5 imagemagick ~/blog/*
    $ grep -iC 5 imagemagick ~/blog/*

  • Displaying lines that do not match
    You might want to find lines that are not commented out in your /etc/apt/sources.list file. To do so, we can use the -v option, and we want to find lines that do not contain the # character. Since the # character is used to comment out lines in Bash, we have to search for this in a way that won't comment out the rest of the command (hint: regular expressions...I plan on doing a post dedicated specifically to the topic of regular expressions in the future), so we can search for this in either of the following two ways:

    $ grep -v "#" /etc/apt/sources.list
    $ grep -v \# /etc/apt/sources.list

  • Displaying only file names that contain matches
    It may be the case that you are really only concerned with the names of the files that contain your search string. To do this, we can use the -l (lower case L) option. I'll return to the ImageMagick example above here:

    $ grep -il imagemagick ~/blog/*

  • Displaying the number of matches per file
    To go one step further from the previous example, you can use the -c option to show you the number of matches you have in each file:

    $ grep -ic imagemagick ~/blog/*

    If you test out the above example, you'll find that it returns all the files that have no matches as well. If you only want to show the number of matches on files that actually have matches, we can use a little bit of redirection to pipe the output of one grep command into the input of another grep command (and a little help with regular expressions):

    $ grep -ic imagemagick ~/blog* | grep -v ":0$"

  • Displaying the line numbers for the matches
    Sometimes it is important to know where in a file the matches are, to help find this, we can use the -n option:

    $ grep -in imagemagick ~/blog/*

Well, that does is for a pretty basic introduction into grep. As usual, there are still some other things that you can do with grep. The biggest thing that you can use with grep that I have not really covered is the use of regular expressions, but that is a topic deserving of its own post.

See you next time

No comments:

Post a Comment