GrepMode

This page is about the Emacs ‘grep’ command. See Also: OccurMode

lgrep and rgrep

With Emacs 22 and later comes the very easy to use yet powerful commands lgrep and rgrep. They both prompt the user for what to search for in a convenient manner. You do not have to know the unix grep command (but if you know it you can use that knowledge too). lgrep searches in the current directory and rgrep searches the current directory tree. rgrep knows about version control systems so it can avoid searching its control directories.

One very conventient thing is that lgrep and rgrep shares command argument history with grep. This mean that you after using them can use the grep command to for example filter the output results, perhaps like this:

    grep -i -nH -e "eshell/" *.el | grep -v defun

Emacs Grep

The Emacs ‘grep’ command lets you run the Unix or GNU/Linux ‘grep’ program, which searches files for lines that match a regular expression (regexp). The Emacs command colors the output and makes found lines clickable: When you click a search hit, Emacs visits the target file at the occurrence.

For example, use ‘M-x grep’ with the following input – in this case, the regexp is a string literal, ‘setq’, and there is only one file to search, ~/.emacs.

  M-x grep -n -e setq ~/.emacs

This lists all lines matching ‘setq’ in your Emacs InitFile, ~/.emacs, showing the filename and the line numbers. When you hit ‘RET’ or click ‘mouse-2’ on one of the lines, the file is opened at the matching line.

The -n, which makes ‘grep’ add line numbers to the output, is necessary to make the search results active, so that you can navigate to them in the ways mentioned above. Since it’s necessary, Emacs automatically includes -n – you need not type it.

Hits from ‘M-x grep’ can be iterated through using `C-x `’. This runs Emacs command ‘next-error’.

Ack

Ack is a replacement for grep, written in Perl, with some powerful features.

Using `grep' and `find' on MS Windows

There are several ways to get a working ‘grep’ and ‘find’ on MS Windows.

Copy grep.exe and find.exe (as well as any necessary .dll files) to Emacs’ bin directory. Emacs will then use these files over any other executables with the same name, including Windows’ own find utility.

Alternatively, you can install grep and find in their default locations and then modify Emacs’ PATH variable (see below).

MSYS

The find and grep utilities from GnuWin32 (below) are very old versions. To have a recent version of find and grep plus other GNU utilities such as egrep you can install MSYS. After installation, put this in your .emacs in order to tell Emacs to use these files over any other executables with the same name, including Windows’ own find utility:

(setenv "PATH"
  (concat
   ;; Change this with your path to MSYS bin directory
   "C:\\MinGW\\msys\\1.0\\bin;"
   (getenv "PATH")))

In recent git installations, using msys from git-bash

(setenv "PATH"
  (concat
   ;; Change this with your path to MSYS bin directory
   "c:\\Program Files\\Git\\usr\\bin;"
   (getenv "PATH")))

GnuWin32

You can obtain ‘grep’ and ‘find’ from the GnuWin32 project:

If you installed ‘GnuWin32’ under, say, “C:\GNU\gnuwin32”, consider adding the following commands to Emacs initialization file:

   (when (or (eq system-type 'windows-nt) (eq system-type 'msdos))
      (setenv "PATH" (concat "C:\\GNU\\gnuwin32\\bin;" (getenv "PATH")))
      (setq find-program "C:\\GNU\\gnuwin32\\bin\\find.exe"
            grep-program "C:\\GNU\\gnuwin32\\bin\\grep.exe"))

Note: setq seems to be unnecessary if PATH variable is modified as above to correct location for find and grep executables.

Note: If paths above contain spaces use additional quotes like this:

   (setq find-program "C:\\\"Program Files (x86)\"\\GnuWin32\\bin\\find.exe"
         grep-program "C:\\\"Program Files (x86)\"\\GnuWin32\\bin\\grep.exe")

It looks like dots and tilde characters needs to be escaped for ‘rgrep’, ‘dired-find’, etc to work:

   (defadvice shell-quote-argument (after windows-nt-special-quote (argument) activate)
     "Add special quotes to ARGUMENT in case the system type is 'windows-nt."
     (when
         (and (eq system-type 'windows-nt) (w32-shell-dos-semantics))
       (if (string-match "[\\.~]" ad-return-value)
           (setq ad-return-value
	        (replace-regexp-in-string
	         "\\([\\.~]\\)"
	         "\\\\\\1"
	         ad-return-value)))))

Cmder

Cmder provides a console emulator for Windows that comes, among others, with Bash and all its base utilities. Including ‘grep’ and ‘find’. Like for ‘MSYS’ and ‘GnuWin32’, add the right directory to the PATH, with the following code in your `.emacs’ file:

;; add cmder <http://cmder.net/> bin directory to the path
(setenv "PATH"
  (concat
   ;; adapt "C:\\tools\\cmder" if you changed cmder default dir
   "C:\\tools\\cmder\\vendor\\git-for-windows\\usr\\bin;"
   (getenv "PATH")))

If you installed Cmder via Chocolatey, it installs by default under `c:\tools\cmder’. You will need to adapt the path in the code above if it is installed somewhere else on your system. If you are not sure, execute `where grep` from a Bash tab in Cmder.

ernie

ernie provides a drop-in replacement for the command-line “grep” program. It is written in 100% Emacs Lisp so it has no dependencies other than Emacs itself. It should work with any of the grep frontends that are supported by emacs. It can also be used stand-alone at the Command Prompt like any other grep. “ernie” is an alias for “grep -r -n -i -e” where you drop the “grp” part and run the rest together.

Grep+: Enhancements to Emacs grep

DrewAdams has written some libraries that provide enhancements to the standard Emacs grep command. See GrepPlus.

Grep Only Marked Files in Dired

DiredPlus binds ‘M-g’ in DiredMode to ‘diredp-do-grep’, which lets you ‘grep’ only the marked files in a Dired buffer – or the next N files if you use a prefix arg. This applies even if the buffer contains inserted subdirectories: all marked files are grepped. Or right-click (‘mouse-3’) and choose Grep from the menu to grep just the file you clicked.

You can also use ‘M-g’ to ‘grep’ marked files in a Dired buffer that has an explicit list of files from different directories, such as all files in a project. See, for example, Marked Files as a Project

Grep All Files in a File Set

With Icicles, you can save sets of file-name completion candidates, either persistently as a project or ephemerally as a variable value. You can then ‘grep’ all of the file in such a saved set using command ‘icicle-grep-saved-file-candidates’. See icicle-grep-saved-file-candidates.

Icicles Search for `grep' or `compile' Results

With Icicles, in a compilation-results buffer such as ‘*Compilation*’ or ‘*grep*’, you can use command ‘icicle-compilation-search’ (`C-`’) to search among the result set (search hits). This is similar to ‘icicle-search’, but when you use ‘C-RET’, ‘C-mouse-2’, ‘C-prior’, ‘C-next’, ‘C-up’, or ‘C-down’, it visits the source code that corresponds to the current line in the compilation buffer.

Using ‘icicle-compilation-search’ with ‘grep’ output gives you multiple levels of regexp searching. In Emacs 22 and later, you can also replace ‘grep’ search-hit text.

igrep for recursive grepping

You might prefer igrep.el, by Kevin Rogers, to standard Emacs ‘grep’, because of its transparent interface. It uses the Unix or GNU/Linux command `find |xargs grep’, and puts the results, including the matched lines, in buffer igrep. The keys bound to ‘next-error’ and ‘prev-error’ work on that buffer and open the corresponding files. No replace capability, though.

Here is the igrep page on the wiki:

igrep-next-error.el (1.2) is an add-on to igrep.el, which highlights the matched text in the source file buffer (see also http://cedet.sourceforge.net/highlightcompile.shtml for this feature)

igrep with relative path

I prefer relative path to full path. – rubikitch

--- igrep.el	2007/11/18 19:11:05	1.1
+++ igrep.el	2007/11/18 19:12:28
@@ -597,9 +597,10 @@
 			    (mapconcat (lambda (file)
 					 (let ((dir (file-name-directory file)))
 					   (if dir
-					       (expand-file-name
-						(file-name-nondirectory file)
-						(igrep-quote-file-name dir))
+					       (file-relative-name
+                                                (expand-file-name
+                                                 (file-name-nondirectory file)
+                                                 (igrep-quote-file-name dir)))
 					     file)))
 				       files " "))
 			  igrep-null-device)))

`mgrep' and `color-grep'

‘mgrep’ and ‘color-grep’ are by Matsushita.

TraverseDirectory

Lisp:traverselisp.el

Do basically the same as ‘rgrep’, but don’t use external programs, only Lisp. Traverselisp have also replacing capabilities: when the regexp is found in all the files of all subdirectories, you can replace this regexp interactively or not, skip a line, or stop. Traverselisp can be launched from dired directly.

You can also get it here with Mercurial:

    hg clone http://freehg.org/u/thiedlecques/traverselisp/

Use with Anything

Anything is a candidate selection framework. Install Lisp:anything-grep.el after installing Anything. Start with ‘M-x anything-grep’, narrow matched lines by typing some patterns(multiple patterns are space-delimited string), select with up/down/pgup/pgdown/C-p/C-n/C-v/M-v, choose with enter,

With C-z the selected line is displayed without quitting anything session.

‘M-x anything-grep-by-name’ greps from predefined location.

Grep-A-Lot

Lisp:grep-a-lot.el

Manage multiple grep results buffers: search results go into a newly created buffer instead of clobbering the contents of the last search results buffer.

Buffers are assigned successive id numbers: *grep*<N>, and you can switch between the buffers either as a ring (next/previous buffer) or as a stack (thus providing a recursive search facility, similar to recursive tags navigation).

You can also get Grep-A-Lot with git:

    git clone git://github.com/ZungBang/emacs-grep-a-lot.git

Hi, I do not think defining global keymap on the top level of elisp is good idea. You should define a function to define keymap like ‘find-function-setup-keys’. – rubikitch

Fixed. Thanks for the tip. – AviRozen

Grep-O-Matic

Lisp:grep-o-matic.el

An extension that automates searching for the word at point in the current repository (requires Lisp:repository-root.el), current directory or the set of currently open files.

You can also get Grep-O-Matic with git:

    git clone git://github.com/ZungBang/emacs-grep-o-matic.git

xargs-grep

grep through large file lists, which don’t fit on the command line. Or file-names have spaces.

See xargs-grep

Find/Grep from shell-mode

While not explicitly about Emacs grep, I use the following recipe to intelligently pattern-search a really large source tree like Chromium or the Linux kernel. The three steps:

  1. build a persistent subset of target files to search, the filelist,
  2. interactively use grep to reduce the filelist to a targetlist,
  3. search the targetlist for patterns.

Step #1: Use find to build the filelist and save it in a local temporary file. For example, to build a list of files from the Chromium source:

  find /opt/chromium/src -wholename '*/.svn' -prune -o -type f -regex ".*\.\(c\|cc\|h\|js\)" -print > CSRC.LST

Then I hand-edit the filelist to remove files in which I am not interested (or redundant in the case of the Linux kernel source tree.) This saves A LOT of time a large trees.

Then I create a temporary file to execute a EmacsLisp eval on a shell-command and capture output for Steps #2 and #3. The shell-command invokes a pipe of ‘grep’ calls to filter down to the targetlist and then one final call to search the targetlist for matching patterns.

Example EmacsLisp command:

  (shell-command "grep '\\.cc' CSRC.LST | xargs grep -n CONTEXT_VALID_ESI" 1)
  (shell-command "grep '.' CSRC.LST | xargs grep -n CHROMIUM" 1)
  (shell-command "grep '.' CSRC.LST | xargs grep -l NACL_OSX | xargs grep -n NACL_LINUX" 1)

Put the cursor at the end of the expression and run ‘eval-last-sexp’ and the ‘grep -n’ output will appear after the shell-command expression.

A simple macro can be triggered on a match line to load the file/lineno into another window or frame depending on your desires.

I have found this to be far easier and quicker than etags or source browsing tools to inspect code. It also uses standard tools with a large number of recipes to follow. I extensively use registers and bookmarks for later referral.

Grep with start directory in modeline

This is what I use:

	(defun mygrep ()
	  "Run grep recursively from the directory of the current buffer or the default directory"
	 (interactive)
	  (let ((dir (file-name-directory (or load-file-name buffer-file-name default-directory))))
	    (let ((command (read-from-minibuffer "Run grep (like this): "
	                                         (cons (concat "grep -nH -r  " dir) 13))))
	          (grep command))))

I use it because the starting directory is explicitly shown in the minibuffer. (With the standard Emacs function I am always wondering from what directory grep will start searching.)


CategoryRegexp CategoryExternalUtilities CategorySearchAndReplace CategoryProgrammerUtils CategoryNavigation