In Emacs how can I easily copy all lines matching a particular regex? Preferably highlighting the matching line开发者_如何转开发s as I type.
occur
gets partway there by coping them into a buffer, but it adds lots of extra stuff.
As of Emacs 24, occur
does in fact provide a simple solution:
C-uM-so .*pattern.*
RET
When you use C-u on its own as the prefix argument, the matching portion of each line is inserted into the *Occur*
buffer, without all the normal adornments.
Note that because only the part of the line matching the regexp is used (unlike a normal occur), you need the leading and trailing .*
to ensure that you capture the entire line.
The details of how occur
treats arguments are a little tricky, so read C-hf occur
RET carefully if you want to know more.
How about this:
(defun copy-lines-matching-re (re)
"find all lines matching the regexp RE in the current buffer
putting the matching lines in a buffer named *matching*"
(interactive "sRegexp to match: ")
(let ((result-buffer (get-buffer-create "*matching*")))
(with-current-buffer result-buffer
(erase-buffer))
(save-match-data
(save-excursion
(goto-char (point-min))
(while (re-search-forward re nil t)
(princ (buffer-substring-no-properties (line-beginning-position)
(line-beginning-position 2))
result-buffer))))
(pop-to-buffer result-buffer)))
You can use keep-lines
to get what you want, copy them, and then undo. For the opposite, there is also flush-lines
to get rid of lines you don't want.
I've been using this happily for a long time:
(defun occur-mode-clean-buffer ()
"Removes all commentary from the *Occur* buffer, leaving the
unadorned lines."
(interactive)
(if (get-buffer "*Occur*")
(save-excursion
(set-buffer (get-buffer "*Occur*"))
(fundamental-mode)
(goto-char (point-min))
(toggle-read-only 0)
(set-text-properties (point-min) (point-max) nil)
(if (looking-at (rx bol (one-or-more digit)
(or " lines matching \""
" matches for \"")))
(kill-line 1))
(while (re-search-forward (rx bol
(zero-or-more blank)
(one-or-more digit)
":")
(point-max)
t)
(replace-match "")
(forward-line 1)))
(message "There is no buffer named \"*Occur*\".")))
(define-key occur-mode-map (kbd "C-c C-x") 'occur-mode-clean-buffer)
You can install package all
. Then M-x all
lets you edit all the lines in the buffer matching a regexp. Instead of editing, you can just copy them too.
精彩评论