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
   ...
lmdic
  • 123
  • 1
  • 7
  • 1
    See also https://emacs.stackexchange.com/questions/11/how-to-add-a-prefix-to-every-line?rq=1 for the related question about adding a prefix. – YoungFrog Jan 11 '18 at 09:33

4 Answers4

24

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.

YoungFrog
  • 3,496
  • 15
  • 27
  • 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. – Henry Jan 11 '18 at 14:49
  • 6
    @Henry Note that you can press `!` to discard the prompt and run the replace on all remaining matches. – N.I. Jan 11 '18 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. – Tankman六四 Mar 17 '19 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.

Henry
  • 203
  • 1
  • 5
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)
Lorem Ipsum
  • 4,327
  • 2
  • 14
  • 35
  • How is this method different from `C-M-%` and `!` discussed [here](https://emacs.stackexchange.com/users/13125/henry) and [here](https://emacs.stackexchange.com/users/10098/najib-idrissi)? – antonio Feb 28 '19 at 00: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. – Lorem Ipsum Feb 28 '19 at 02:55
  • Fixed: How is this method different from `C-M-%` and `!` discussed [here](https://emacs.stackexchange.com/questions/38022/how-to-add-a-suffix-to-every-line-of-a-text/48097?noredirect=1#comment59852_38023) and [here](https://emacs.stackexchange.com/questions/38022/how-to-add-a-suffix-to-every-line-of-a-text/48097?noredirect=1#comment59861_38023)? – antonio Feb 28 '19 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)
antonio
  • 1,762
  • 12
  • 24