How to Write grep in Emacs Lisp
This page shows you how to write a emacs lisp script to search files, similar to unix grep.
I want to write a elisp script that reports files in a dir that contain a string n times. The script is expected to search thru 5 thousand files.
Here's a very simple version. It reports number of matches.
;; -*- coding: utf-8 -*- ;; 2010-03-27 ;; print file names of files that have n occurrences of a string, of a given dir ;; input dir (setq inputDir "~/web/" ) ; In elisp, dir path should end with a slash (defun my-process-file (fPath) "Process the file at FPATH …" (let (myBuffer p1 p2 (ii 0) searchStr) (when (and (not (string-match "/xx" fPath))) ; exclude some dir (with-temp-buffer (insert-file-contents fPath nil nil nil t) (setq searchStr "somesearchstring" ) ; search string here (goto-char 1) (while (search-forward searchStr nil t) (setq ii (1+ ii))) ;; report if the occurrence is not n times (when (not (= ii 0)) (princ (format "this many: %d %s\n" ii fPath))))))) ;; traverse the dir (require 'find-lisp) (let (outputBuffer) (setq outputBuffer "*my occur output*" ) (with-output-to-temp-buffer outputBuffer (mapc 'my-process-file (find-lisp-find-files inputDir "\\.html$")) (princ "Done deal!")))
The code is pretty simple. At the bottom, the code visits every file in a dir. For each file, it calls
(my-process-file fPath). The “my-process-file” function creates a temp buffer, inserts the file content in it, then do search inside the temp buffer. We do this because it's faster.
(with temp buffer, emacs doesn't do syntax-coloring (which is very slow), disables undo, or any other thing emacs normally do when opening a file for interactive edit.)
To run the file, you can call
〔➤ Emacs: How to Evaluate Emacs Lisp Code〕
〔➤ Emacs Lisp: Run Current File〕
The elisp idioms used in this script are explained at: Text Processing with Emacs Lisp Batch Style.
On 5k files, the script takes 20 seconds on a average year 2011 computer. (when files are not cached.)
Why can't i just call the unix grep command?
Emacs Package: xah-find.el
For the full featured version of this command, see the package Emacs: Find/Replace in Pure Elisp xah-find.el.
For applications of this script, with slight variations, see:
- Emacs Lisp: Find String Inside HTML Tag
- Emacs Lisp Batch Text processing: Grep Find Replace Variations
For simple example of writing grep/sed/awk in Python and Perl, see: