Getting Just the Filename from a Search

Problem

You need to find the files in which a certain string appears. You don’t want to see the line of text that was found, just the filenames.

Solution

Use the -l option of grep to get just the filenames:

$ grep -l printf *.c
both.c
good.c
somio.c

Discussion

If grep finds more than one match per file, it still only prints the name once. If grep finds no matches, it gives no output.

This option is handy if you want to build a list of files to be operated on, based on the fact that they contain the string that you’re looking for. Put the grep command inside $( ) and those filenames can be used on the command line.

For example, to remove the files that contain the phrase “This file is obsolete,” you could use this shell command combination:

$ rm -i $(grep -l 'This file is obsolete' * )

We’ve added the -i option to rm so that it will ask you before it removes each file. That’s obviously a safer way to operate, given the power of this combination of commands.

bash expands the * to match every file in the current directory (but does not descend into sub-directories) and passes them as the arguments to grep. Then grep produces a list of filenames that contain the given string. This list then is handed to the rm command to remove each file.

See Also

  • man grep

  • man rm

  • 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)

  • Connecting Two Programs ...

Get bash Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.