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 t ;; (and (not (string-match "/xx" fPath)) ) ; exclude some dir ;; create a temp buffer. Work in temp buffer. Faster. (setq myBuffer (get-buffer-create " myTemp")) (set-buffer myBuffer) (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)) ) (kill-buffer myBuffer) ) )) ;; traverse the dir (require 'find-lisp) (let (outputBuffer) (setq outputBuffer "*xah 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 font-locking (which is resource intensive), 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? See: Problems of Calling Unix grep in Emacs.
For the full version of this command, see the package
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: