Emacs: Searching for Text in Files (grep, find)

Perm url with updates: http://xahlee.org/emacs/emacs_grep_find.html

This page is a tutorial on using Emacs to search text. For example, list lines contain a word, list files that contains a word.

If you came from unix/linux background, then you know about unix's {grep, find} commands that are very useful. You can call unix shell commands within emacs by shell or shell-command. (See: Emacs Shell Tutorial.)

Emacs has its own elisp commands that makes it more convient. Because the emacs versions will highlight the matched text in the resulting output, and also link the matched file, allowing you to see better, and jump to files directly.

Some of these commands are written entirely in elisp, some work as a wrapper to the unix command tool. Here are the most often used emacs text-searching related commands.

List Lines Matching a String, for a Single File

Call list-matching-lines. It'll list all lines in the current file that matching a given text. Here's a sample output:

5 matches for "cat" in buffer: alice-ch01.html
    122:should think! (Dinah was the cat.) I hope they'll remember her
    125:might catch a bat, and that's very like a mouse, you know. But do
    126:cats eat bats, I wonder? And here Alice began to get rather
    128:Do cats eat bats? Do cats eat bats? and sometimes, Do bats eat
    129:cats? for, you see, as she couldn't answer either question, it

Clicking the line will jump to the match location in the file.

Note that “catch” is also a match, because it contains “cat”. If you want to match with word boundary, use \b, like this \bcat\b. (See: Emacs: Text Pattern Matching (regex tutorial).)

There's also delete-matching-lines and delete-non-matching-lines. See: List Matching Lines and Delete Matching Lines in Emacs.

List All Files of a Folder that Contain Match Text

Call grep to list all files in the current folder. (You can first call dired to a folder you want to do the search.) It will prompt you like this:

grep -nH -e ▮

For example, if you give this input grep -nH -e "Cheshire" *html, which will list all files ending in “html” that contains the word “Cheshire”. If you want case insensitive search, add a “-i” in the grep option. Here's a sample output:

-*- mode: grep; default-directory: "c:/Users/h3/web/xahlee_org/p/alice/" -*-
Grep started at Thu Nov 17 02:41:03

grep -nH -e "Cheshire" *html
alice-ch06.html:109:<figure><img src="http://xahlee.org/emacs/i/jt/p20/alice_06b-duchess_kitchen.png" alt="Cook, Duchess, Cheshire Cat, Baby, and Alice" width="854" height="711"></figure>
alice-ch06.html:132:<p>«It's a Cheshire cat,» said the Duchess, «and that's why.
alice-ch06.html:140:<p>«I didn't know that Cheshire cats always grinned; in fact, I
alice-ch06.html:274:Cheshire Cat sitting on a bough of a tree a few yards off.</p>
alice-ch06.html:277:<figure><img src="http://xahlee.org/emacs/i/jt/p20/alice_06d-cheshire.png" alt="Alice speaks to Cheshire Cat" width="863" height="1251"></figure>
alice-ch06.html:283:<p>«Cheshire Puss,» she began, rather timidly, as she did not at all
alice-ch06.html:378:<figure><img src="http://xahlee.org/emacs/i/jt/p20/alice_06e-chesire_grin.png" alt="Cheshire Cat fading to smile" width="846" height="548"></figure>
alice-ch08.html:240:grin, and she said to herself «It's the Cheshire Cat: now I shall
alice-ch08.html:276:<p>«It's a friend of mine — a Cheshire Cat,» said Alice: «allow me to
alice-ch08.html:323:<p>When she got back to the Cheshire Cat, she was surprised to find
alice-ch08.html:335:<figure><img src="http://xahlee.org/emacs/i/jt/p20/alice_08d-execution.png" alt="Executioner argues with King about cutting off Cheshire Cat's head" width="714" height="919"></figure>

Grep finished (matches found) at Thu Nov 17 02:41:03

Note that the matched texts are not highlighted. That's too bad. To highlight it, you can call highlight-phrase.

List Some Files in a Folder and or Sub-Folders

  • Call rgrep for all files and files in sub-folders.
  • Call lgrep to list only some files by using a text pattern (regex) on file names first.

You can also use grep-find. “grep-find” is similar to {grep, rgrep, lgrep}. It uses a combination of unix's grep and find. It will prompt you with this:

find . -type f -print0 | xargs -0 -e grep -nH -e MySearchStr▮

Just type your search string at the cursor position. (the exact command prompted may be slightly different depending on your OS.)

List Matched Files in Dired

How to have the unix “find” result shown in dired?

Call find-dired.

Explanation: In unix, there's a very useful command that list files in a directory with a particular property. For example, if you want to list all files ending in “.html” in a directory and all subdirectories under it, you can do find /Users/jane/ -name "*.html" -print.

However, the result is a textual output. Let's say you want to run a word count “wc” command on all such files. You can use “find”'s option “-exec”, or in combination with “xargs” command. For example: find . -name "*.html" -print | xargs -l -i wc {}.

However, sometimes you want to do several complicated things with this set of files, and you want to do them interactively. For example, some of such files you want to word count, some of them you want to run another command on, and some of them you need to rename, and what to do depends on the previous commands. In this case, it will be useful, to have this list of files shown in emacs's dired mode, then you can use all emacs dired power to manipulate these files.

Stepping Thru Files of Matching Text in Dired

While in dired, you can step thru all files that matches a text pattern. In dired, call “dired-do-search” 【A】. It will prompt you for a search string, then display the first file of the match, with your cursor placed at the matching location.

To go to next occurrence, press 【Meta+,】 (tags-loop-continue).

Find & Replace

If you want to do find & replace on multiple files, you can first call dired or find-dired, then mark the target files. Then, call dired-do-query-replace-regexpQ】 to do the actual find & replace. For detail, see: Interactively Find & Replace String Patterns on Multiple Files .

Popular posts from this blog

11 Years of Writing About Emacs

does md5 creates more randomness?

Google Code shutting down, future of ErgoEmacs