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

, , …,

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

Calling Linux Shell Commands

Emacs can call Linux shell commands, such as {grep, find}. You can call shell commands by shell or shell-command. 〔☛ Emacs Shell Tutorial

On Microsoft Windows, you can install unix commands by cygwin. 〔☛ Installing Cygwin Tutorial

Emacs has its own elisp commands that make 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 commands. 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 matches 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.

Notice in the above output that “catch” is also a match, because it contains “cat”. If you want to match with word boundary, use \b, like this \bcat\b. 〔☛ 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 a Text Pattern (requires Linux grep)

Call grep to list all files in the current folder. The current folder is usually the folder the current opend file is in. (You can first call dired to a folder you want.) 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="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="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="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="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

On Linux, by default, the matched text are highlighted.

On Window, 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

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 . -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-searchA】. It will prompt you for a search string, then open 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 .

Jump to Current Dir

Here's a very convient command.

dired-jump → Jump to the dir of the current file.

blog comments powered by Disqus