6

Windows 10, Emacs 25.1

Suppose I have the following text (about 100 rows):

 ic_m_sales ic_m_activity_report ic_m_messanges ic_m_products_name ic_m_change_store ic_m_faq ... 

How to add the same suffix (_inactive) to every line of the text ? The result must be like this:

 ic_m_sales_inactive ic_m_activity_report_inactive ic_m_messanges_inactive ic_m_products_name_inactive ic_m_change_store_inactive ic_m_faq_inactive ... 
1

4 Answers 4

25

Very easily, fortunately.

Use C-M-% (which runs the command query-replace-regexp), use the regexp (regular expression) $ (this matches exactly at the end of line) and replace it with your text. And that's it!

Another possibility involves Magnars Sveen's excellent multiple-cursors.el : select lines, use M-x mc/edit-lines then hit C-e (end-of-line) and start typing. Really magic.

gif showing multiple-cursors.el in action

You can also of course use keyboard macros. With cursor somewhere in the first line, hit F3 (to start recording the macro), then hit C-e and start typing. Once you're happy with that line, simply go to next-line (e.g. with C-n) and hit F4 (to stop recording the macro). Nothing happened ? That's fine : start hammering F4 until you're happy with the result. Alternative to hammering: using a numerical argument (as in C-u 123 F4) can save your keyboard some pain...

gif showing keyboard macro in action

I'll also mention string-rectangle (C-x r t) which works nicely if your lines all end up in the same column, but that does not seem to be the case from your example.

3
  • 2
    My preference is to run M-x replace-regexp, then replace the regex $ with the text as you describe...I don't like the prompt. Commented Jan 11, 2018 at 14:49
  • 6
    @Henry Note that you can press ! to discard the prompt and run the replace on all remaining matches. Commented Jan 11, 2018 at 17:08
  • C-M-% doesn't work in a Linux terminal because it can't be control-sequenced, so you need the GUI version of emacs or use C-x r t instead. Both work as well if you first mark a region. Commented Mar 17, 2019 at 23:39
2

Depending on your use-case, you might also use a macro.

The concept is to record some keyboard actions, and then have emacs repeat them for you.

  • Define macro
    1. Begin recording macro: C-x (
    2. Jump to end of line: C-e
    3. Type text, or yank from the kill-ring (ie, paste previously copied text): C-y
    4. Move to next line: C-n
    5. Finish recording macro: C-x )
  • Execute macro
    1. Trigger macro once: C-x e
    2. Repeat macro (if next key press after executing the macro): e

Macros don't scale very well, but for one-off, complicated text reorganization, it's fast, dirty, and effective.

1
  • Or maybe use multicursors? link Commented Jan 11, 2018 at 16:39
1

My preferred method is:

  1. Select the region, using something like C-S-n or C-<SPC>
  2. M-x replace-regexp, then $, and <text-to-append>. Press <RET>.

The $ indicates the end of the line. The replace-regexp function will replace the end of the line with your <text-to-append>.

There isn't a default binding for replace-regexp, but you could create your own with something like:

(global-set-key (kbd "C-c a") 'replace-regexp) 
3
  • How is this method different from C-M-% and ! discussed here and here? Commented Feb 28, 2019 at 0:13
  • The emphasis is on replace-regexp rather than query-replace-regexp. I felt it deserved more than a comment, as it's my main go-to for this situation. The links you give are to profiles. I'm not sure what you're referencing. Commented Feb 28, 2019 at 2:55
  • Fixed: How is this method different from C-M-% and ! discussed here and here? Commented Feb 28, 2019 at 10:21
0

A little complement to make @YoungFrog answer a bit more practical.

Clearly at the end of the lines there might be some random white spaces you not even notice. Not clearing them means replaced text is randomly like that:

ic_m_sales _inactive ic_m_activity_report _inactive ic_m_messanges _inactive ic_m_products_name _inactive ic_m_change_store _inactive ic_m_faq _inactive ... 

Clearing the spaces is even more boring than adding the suffixes.

However, you can select the region to suffix and use the command C-M-% or M-x query-replace-regexp, then just type:

SPACE*$ENTER_inactive

Now you are replacing the spaces before the newlines, if any.

If the regexp above is inconvenient to type/remember, just define once and for all the function:

(defun region-suffix (r1 r2) (interactive "r") (perform-replace " *$" (read-string "Enter suffix:") nil 'regexp nil nil nil r1 r2 nil nil)) 

Now, when you select the region to suffix and type M-x region-suffix, you are prompted to enter the suffix and you are done.

If that is a common operation for you, bind the region-suffix function to some spare keys, e.g:

(global-set-key (kbd "C-x p") 'region-suffix) 
2
  • As noted in the docstring of perform-replace it shouldn't be used in code. Better use re-search-forward and replace-match. Commented Feb 27, 2019 at 23:18
  • @clemera: I will fix it as time allows Commented Feb 28, 2019 at 0:15

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.