17.6. Searching: grep and find

A common task is to search for specific files or for specific content within files. The find command is useful for finding a file or directory whose name has a specific pattern, whereas the grep command is useful for searching for a specific pattern within a file or set of files.

17.6.1. The find Command

The find command performs a recursive search of a filesystem (at a given start point in the directory structure), to find any files. When run with the -name <search pattern> command line option, find searches for all files (and directories) with a name matching the given search pattern. The search pattern is a regular expression that includes character literals and special characters or sub-patterns that specify general patterns. One special character commonly used in regular expressions is `*`. It means "match with one or more of any character". So for the search pattern "hello*", hello1, hellothere, and hello_123_XYZ all match the pattern. Here are a few examples of the find command to find files:

$ find ./ -name dog.c    # from current directory (./) find all files named dog.c
$ find ./ -name "*.c"    # from ./ find all files that end with .c
$ find ./ -name "temp*"  # from ./ find all files that that start with temp

There are many other command line options to the find command, allowing users to configure its search behavior in different ways. See its man page for more information.

17.6.2. The grep Command

The grep command finds patterns within a file or within a set of files. It can filter data from a source to a destination based on pattern matching. The grep command takes two command line arguments, a search pattern regular expression, and a file (or set of files) to search in for matching patterns. It outputs every line in the file (or set of files) that has a matching occurrence of the pattern. Like find, grep also has many command line options to tailor its search. Below are a few examples of the grep command to find patterns in a file(s). One of the files used in these examples is the temp file, whose contents are the following:

hello
1
hello there
2
hello goodbye hello
3
there hello
4
hello there
  • Search for all occurrences of "hello" in the file temp:

    $ grep hello temp
    hello
    hello there
    hello goodbye hello
    there hello
    hello there
  • Search for occurrences of "hello there" in the file temp. In this example, because the search pattern has space characters in it, the pattern needs to be inside double quotes.

    $ grep "hello there" temp
    hello there
    hello there
  • Include the file line numbers with matches (-n command line option):

    $ grep -n "hello there" temp
    3:hello there
    9:hello there
  • Search for all patterns that start with any upper-case alphabetic character ([A-Z]) followed by an o followed by one or more characters `*`:

    $ grep "[A-Z]o*" temp
  • Search for all patterns that start with any lower-case alphabetic character ([a-z]) followed by an o followed by one or more characters `*`:

    $  grep "[a-z]o*" temp
    hello
    hello there
    hello goodbye hello
    there hello
    hello there
  • Search for main in all files ending in .c:

    $ grep main *.c
    function.c:int main(void) {
    hello.c:int main(void) {
    string.c:int main(void) {
    structfunc.c:int main(void) {
    types_scanf.c:int main(void) {
  • Search for main in all files ending in .c, and list the filename and the line number of all matches:

    $ grep -H -n main *.c
    function.c:21:int main(void) {
    hello.c:13:int main(void) {
    string.c:11:int main(void) {
    structfunc.c:17:int main(void) {
    types_scanf.c:13:int main(void) {
  • Recursively grep (-r) for hello in all files starting in the CS31 subdirectory:

    $ grep -r hello  ~/cs31

There are many command line options to grep to configure its search in different ways.

17.6.3. References

For more information see: