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/" ) ;; add a ending slash if not there. In elisp, dir path should end with a slash (when (not (string= "/" (substring inputDir -1) )) (setq inputDir (concat inputDir "/") ) ) (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 (if (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: Execute/Compile 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.
Why can't i just call the unix grep command?
For the full version of this command, see the package
For applications of this script, with slight variations, see:
For simple example of writing grep/sed/awk in Python and Perl, see: