Lassen Sie `delete-duplicate-lines` Leerzeilen und bestimmte Wörter ignorieren

9

Ich bearbeite einen Text im Organisationsmodus. Mehrere Zeilen werden wiederholt, da sie Teil verschiedener Dateien aus demselben Thema sind.

Ich möchte delete-duplicate-linesdie wiederholten Zeilen löschen, aber der Befehl entfernt auch die leeren Zeilen, was ich nicht möchte (sonst hätte ich keine Absätze!). Ich möchte bestimmte Wörter ignorieren, die nur in Zeilen vorkommen, z. B. "Fortsetzen" . Sie werden im Text häufig wiederholt, aber ich möchte sie beibehalten, da dies erforderlich ist.

Shackra
quelle

Antworten:

5

Leerzeilen ignorieren

Sie können delete-duplicate-linesLeerzeilen ignorieren, indem Sie sie über aufrufen

C-u C-u C-u M-x delete-duplicate-lines RET

Wenn Sie C-ubeim Aufrufen nicht so oft delete-duplicate-linesdrücken müssen, können Sie ihn in einen benutzerdefinierten Befehl einschließen und diesen Befehl an eine Tastenfolge Ihrer Wahl binden:

(defun delete-duplicate-lines-keep-blanks ()
  (interactive)
  (delete-duplicate-lines (region-beginning) (region-end) nil nil t))

(global-set-key (kbd "C-c d") 'delete-duplicate-lines-keep-blanks)

Ignorieren von Zeilen, die mit regulärem Ausdruck übereinstimmen

Was den zweiten Teil Ihrer Frage betrifft, glaube ich nicht, dass Sie mit der integrierten Version von das erreichen können, was Sie wollen delete-duplicate-lines. Sie können jedoch eine geänderte Version des Befehls verwenden (die standardmäßig auch Leerzeilen enthält):

(defun delete-duplicate-lines
    (beg end keep &optional reverse adjacent keep-blanks interactive)
  (interactive
   (progn
     (barf-if-buffer-read-only)
     (list (region-beginning) (region-end)
           (read-string "Keep lines matching regexp: ") ; Prompt for regexp to keep
           (equal current-prefix-arg '(4))
           (equal current-prefix-arg '(16))
           t                                            ; Keep blanks by default
           t)))
  (let ((lines (unless adjacent (make-hash-table :test 'equal)))
        line prev-line
        (count 0)
        (beg (copy-marker beg))
        (end (copy-marker end)))
    (save-excursion
      (goto-char (if reverse end beg))
      (if (and reverse (bolp)) (forward-char -1))
      (while (if reverse
             (and (> (point) beg) (not (bobp)))
               (and (< (point) end) (not (eobp))))
        (setq line (buffer-substring-no-properties
                (line-beginning-position) (line-end-position)))
        (if (or (and keep-blanks (string= "" line))
                (string-match keep line))               ; Ignore line if it
                                                        ; matches regexp to keep
            (forward-line 1)
          (if (if adjacent (equal line prev-line) (gethash line lines))
              (progn
                (delete-region (progn (forward-line 0) (point))
                               (progn (forward-line 1) (point)))
                (if reverse (forward-line -1))
                (setq count (1+ count)))
            (if adjacent (setq prev-line line) (puthash line t lines))
            (forward-line (if reverse -1 1))))))
    (set-marker beg nil)
    (set-marker end nil)
    (when interactive
      (message "Deleted %d %sduplicate line%s%s"
               count
               (if adjacent "adjacent " "")
               (if (= count 1) "" "s")
               (if reverse " backward" "")))
    count))

Diese Version von delete-duplicate-linesfordert Sie zur Eingabe eines regulären Ausdrucks auf und behält alle Zeilen bei, die mit dem regulären Ausdruck übereinstimmen. Um beispielsweise alle Zeilen, die aus dem Wort bestehen, Resumebeizubehalten, würden Sie Folgendes tun:

M-x delete-duplicate-lines RET ^Resume$ RET

itsjeyd
quelle