Sifting Through Files for a String

Problem

You need to find all occurrences of a string in one or more files.

Solution

The grep command searches through files looking for the expression you supply:

$ grep printf *.c
both.c:    printf("Std Out message.
", argv[0], argc-1);
both.c:    fprintf(stderr, "Std Error message.
", argv[0], argc-1);
good.c:    printf("%s: %d args.
", argv[0], argc-1);
somio.c:        // we'll use printf to tell us what we
somio.c:        printf("open: fd=%d
", iod[i]);
$

The files we searched through in this example were all in the current directory. We just used the simple shell pattern *.c to match all the files ending in .c with no preceding pathname.

Not all the files through which you want to search may be that conveniently located. Of course, the shell doesn’t care how much pathname you type, so we could have done something like this:

$ grep printf ../lib/*.c ../server/*.c ../cmd/*.c */*.c

Discussion

When more than one file is searched, grep begins its output with the filename, followed by a colon. The text after the colon is what actually appears in the files that grep searched.

The search matches any occurrence of the characters, so a line that contained the string “fprintf” was returned, since “printf” is contained within “fprintf”.

The first (non-option) argument to grep can be just a simple string, as in this example, or it can be a more complex regular expression (RE). These REs are not the same as the shell’s pattern matching, though they can look similar at times. Pattern matching is so powerful that you may find yourself relying on it to the point where you’ll start using “grep” as a verb, and wishing you could make use of it everywhere, as in “I wish I could grep my desk for that paper you wanted.”

You can vary the output from grep using options on the command line. If you don’t want to see the specific filenames, you may turn this off using the -h switch to grep:

$ grep -h printf *.c
  printf("Std Out message.
", argv[0], argc-1);
  fprintf(stderr, "Std Error message.
", argv[0], argc-1);
  printf("%s: %d args.
", argv[0], argc-1);
     // we'll use printf to tell us what we
     printf("open: fd=%d
", iod[i]);
$

If you don’t want to see the actual lines from the file, but only a count of the number of times the expression is found, then use the -c option:

$ grep -c printf *.c
both.c:2
good.c:1
somio.c:2
$

Warning

A common mistake is to forget to provide grep with a source of input. For example grep myvar. In this case grep assumes you will provide input from STDIN, but you think it will get it from a file. So it just sits there forever, seemingly doing nothing. (In fact, it is waiting for input from your keyboard.) This is particularly hard to catch when you are grepping a large amount of data and expect it to take a while.

See Also

  • man grep

  • man regex (Linux, Solaris, HP-UX) or man re_format (BSD, Mac) for the details of your regular expression library

  • Mastering Regular Expressions by Jeffrey E. F. Friedl (O’Reilly)

  • Classic Shell Scripting by Nelson H.F. Beebe and Arnold Robbins (O’Reilly), Sections 3.1 and 3.2

  • Chapter 9 and the find utility, for more far-reaching searches

  • Expecting to Change Exported Variables

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.51.36