Gabriel Saldaña's blog

personal blog, photography and programming

Emacs tip: How to edit multiple files on several directories in less than a minute

Recently I had to edit multiple files (239 in total) scattered in a bunch of directories and subdirectories. Here’s a quick and safe way to do it.

What I had to do was add the Google Analytics script snippet to a part of a website that was being maintained by a pair of <your favorite bad adjective here> developers.

So, first I thought of using sed or awk or something like that, but doing a quick search replace like that without checking if my match is correct in every instance in a bunch of files can lead to a big disaster.

But wait, I have Emacs! So, the first thing to do is find and list all the files you need to edit.

  1. Open the parent directory

    Use dired to open the parent directory where all the files and directories are. Open dired with:

    M-x find-dired
    


    and enter the path for the directory.

  2. Find the files

    Emacs will then prompt: “Run find (with args):”. So if you need to edit all HTML files, or in my case, PHP files, you type:

    -name "*.php"
    

    If you want all files regardless of type, enter

    -type f
    


    Basically you can type in any arguments you want if you know how to use the find command.

  3. Mark the files you need to edit

    A list of all found files will appear in a dired buffer. Now you need to mark the files you want to work with. Typically you’ll mark all files since you already filtered them. Press t to toggle marks and all files will get marked. Or if you want to hand pick them, move the cursor to the file line or name and press m.

  4. Do the find and replace

    Type: Press Q or M-x dired-do-query-replace-regexp to run the find and replace command. It will prompt you first for the text you want to find, then will prompt you with the text you want to replace it with.

    Then Emacs will start the find and replace operation, and will prompt you on every find if you want to replace the text or skip it. To replace, type y, to skip to the next find type n. To replace all occurrences without asking, type !. To cancel the operation, type C-g.

  5. Save the edited files

    Now that you’ve made all these changes, you need to save the files. To avoid saving manually all files, you can open ibuffer

    M-x ibuffer

    Which will list all you opened files (called buffers). Now, like in dired, you need to mark the buffers you want to work with. To mark all unsaved files, type * u and then type S (that’s shift+s, for the capital letter) to save them.

Done!

Easy and without a sweat.

photo by zyphichore on Flickr.

About the author

Gabriel Saldaña Gabriel Saldaña is a web developer, photographer and free software advocate. Connect with him on and Twitter

Posted Under
Tagged

Post navigation

14 thoughts on “Emacs tip: How to edit multiple files on several directories in less than a minute

  1. Geir says:

    An even easier way to save all files (without prompting) is to invoke save-some-buffers with a prefix: C-u C-x s.

  2. Daniel says:

    vim `find . -name ….`
    :bufdo %s/replaceThis/withThat/ge | update

  3. Mike Seth says:

    Or you could just C-x C-f like usual and use wildcards.

  4. Nu says:

    Hey! THIS IS AWESOME. I was just facing exactly the same challenge this weekend, and this is EXACTLY what I wanted.

  5. Maxime Biais says:

    When I need this kind of replacements I use perl with this command:


    perl -p -i -e 's/SOMETHING/REPLACEMENT/' $(find . -name "*html")

  6. Grok2 says:

    Hey, this is neat. While this can be done in a variety of ways using many different tools, I surely will be trying this one out the next time I need to search-replace in multiple files — I like the fact that you can set things up to query before actually performing the replace. It’s cool to be able to use the same tool (emacs) to do multiple tasks. Great.

  7. Nu,
    I’m glad you found this tip useful. I always forget the procedure, so I decided to ppst it. Maybe I should post some more tips.

  8. Daniel,

    Thanks, but it reminds me of this little cartoon:
    http://www.flickr.com/photos/rhine/2763293190/

  9. Ken says:

    In the find-dired example, when emacs asks you to “Run find (with args): “, you should type:

    -name “*.php”

    You need the quotation marks around *.php otherwise you will get an error.

  10. Michael Terry says:

    Yes, as people love to point out, there are more compact ways to do a simple find and replace in a bunch of files. What’s good about this method is you are verifying the replacements. In my experience, I usually match things I don’t want to replace, and I’m pretty sure you do too, meaning finding and replacing with one line of code is a fairly irresponsible thing to do.

  11. I’d never seen M-x find-dired before – I don’t think I’ll ever learn everything about Emacs.

  12. Pingback: Freiheit 2 » Blog Archiv » links for 2008-08-21

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: