tutorial source para mac descargar code emacs elisp

source - Cómo borrar las líneas de repetición en emacs.



emacs para mac (4)

En Linux, seleccione región y escriba

M-| uniq <RETURN>

El resultado sin duplicados está en el nuevo búfer.

Tengo un texto con muchas líneas, mi pregunta es ¿cómo eliminar las líneas repetidas en emacs? Uso del comando en paquetes emacs o elisp sin utils externos.

por ejemplo:

this is line a this is line b this is line a

para eliminar la tercera línea (igual que la primera línea)

this is line a this is line b


Pon este código a tu .emacs:

(defun uniq-lines (beg end) "Unique lines in region. Called from a program, there are two arguments: BEG and END (region to sort)." (interactive "r") (save-excursion (save-restriction (narrow-to-region beg end) (goto-char (point-min)) (while (not (eobp)) (kill-line 1) (yank) (let ((next-line (point))) (while (re-search-forward (format "^%s" (regexp-quote (car kill-ring))) nil t) (replace-match "" nil nil)) (goto-char next-line))))))

Uso:

M-x uniq-lines


Si tiene Emacs 24.4 o una versión más reciente, la forma más limpia de hacerlo sería la nueva función de delete-duplicate-lines . Tenga en cuenta que

  • esto funciona en una región, no en un búfer, así que seleccione el texto deseado primero
  • Mantiene el orden relativo de los originales, matando a los duplicados.

Por ejemplo, si su entrada es

test dup dup one two one three one test five

Mx delete-duplicate-lines lo haría

test dup one two three five

Tiene la opción de buscar desde atrás prefijándolo con el argumento universal ( Cu ). El resultado sería entonces

dup two three one test five

El crédito va a emacsredux.com .

Otras opciones de rotonda, que no dan el mismo resultado, están disponibles a través de Eshell:

  1. sort -u ; No mantiene el orden relativo de los originales.
  2. uniq ; Peor necesita su entrada para ser ordenado

(defun unique-lines (start end) "This will remove all duplicating lines in the region. Note empty lines count as duplicates of the empy line! All empy lines are removed sans the first one, which may be confusing!" (interactive "r") (let ((hash (make-hash-table :test #''equal)) (i -1)) (dolist (s (split-string (buffer-substring-no-properties start end) "$" t) (let ((lines (make-vector (1+ i) nil))) (maphash (lambda (key value) (setf (aref lines value) key)) hash) (kill-region start end) (insert (mapconcat #''identity lines "/n")))) (setq s ; because Emacs can''t properly ; split lines :/ (substring s (position-if (lambda (x) (not (or (char-equal ?/n x) (char-equal ?/r x)))) s))) (unless (gethash s hash) (setf (gethash s hash) (incf i))))))

Una alternativa:

  • No utilizará el historial de deshacer para almacenar coincidencias.
  • En general, será más rápido (pero si busca la velocidad máxima, cree un árbol de prefijos).
  • Tiene el efecto de reemplazar todos los caracteres de nueva línea anteriores, independientemente de lo que fueran con /n (estilo UNIX). Lo que puede ser una ventaja o una desventaja, dependiendo de su situación.
  • Podría hacerlo un poco mejor (más rápido), si vuelve a implementar split-string de manera que acepte caracteres en lugar de expresiones regulares.

Un poco más largo, pero, quizás, una variante un poco más eficiente:

(defun split-string-chars (string chars &optional omit-nulls) (let ((separators (make-hash-table)) (last 0) current result) (dolist (c chars) (setf (gethash c separators) t)) (dotimes (i (length string) (progn (when (< last i) (push (substring string last i) result)) (reverse result))) (setq current (aref string i)) (when (gethash current separators) (when (or (and (not omit-nulls) (= (1+ last) i)) (/= last i)) (push (substring string last i) result)) (setq last (1+ i)))))) (defun unique-lines (start end) "This will remove all duplicating lines in the region. Note empty lines count as duplicates of the empy line! All empy lines are removed sans the first one, which may be confusing!" (interactive "r") (let ((hash (make-hash-table :test #''equal)) (i -1)) (dolist (s (split-string-chars (buffer-substring-no-properties start end) ''(?/n) t) (let ((lines (make-vector (1+ i) nil))) (maphash (lambda (key value) (setf (aref lines value) key)) hash) (kill-region start end) (insert (mapconcat #''identity lines "/n")))) (unless (gethash s hash) (setf (gethash s hash) (incf i))))))