2010-02-18 3 views
12

В Emacs, как я могу легко скопировать все строки, соответствующие определенному регулярному выражению? Предпочтительно выделять совпадающие строки по мере ввода.Emacs копировать соответствующие строки

occur получает часть там, копируя их в буфер, но он добавляет много дополнительного материала.

ответ

11

Как об этом:

(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))) 
+0

Как вы это делаете так быстро? Это также совершенно другое решение для того, что я ожидал. Я предполагал, что он будет использовать режим ввода. Благодарю. – Singletoned

+0

Ум ... это обычный тип дела. Здесь действительно всего 3 вещи. 1) сделать буфер, 2) искать текущий буфер, 3) вставить результат поиска в новый буфер ... –

2

Я использую это с удовольствием в течение длительного времени:

(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) 
9

Вы можете использовать keep-lines, чтобы получить то, что вы хотите, копировать их, а затем отменить , Для противоположного, есть также flush-lines, чтобы избавиться от линий, которые вы не хотите.

21

По состоянию на Emacs 24, occur это на самом деле обеспечивают простое решение:

CuMsо.*pattern.*RET

При использовании Cu само по себе, как префикс, соответствующая часть каждой строки вставляется в буфер *Occur* без всех нормальных украшений.

Обратите внимание, что, поскольку используется только часть строки, соответствующая регулярному выражению (в отличие от обычного), вам необходимо вести ведущую и конечную .*, чтобы обеспечить захват всей строки.

Детали того, как occur обрабатывает аргументы немного сложнее, так что читать С-НеoccurRET внимательно, если вы хотите узнать больше.

+0

Работает как очарование! Это должен быть принятый ответ. :) –

2

Вы можете установить пакет all. Затем M-x all позволяет редактировать все строки в буфере, соответствующие регулярному выражению. Вместо редактирования вы можете просто скопировать их.

Смежные вопросы