我有很多行的文本,我的问题是如何删除 emacs 中的重复行?在没有外部工具的 emacs 或 elisp 包中使用该命令。
例如:
this is line a
this is line b
this is line a
删除第 3 行(与第 1 行相同)
this is line a
this is line b
如果您有 Emacs 24.4 或更新版本,最简洁的方法就是使用新delete-duplicate-lines
功能。注意
例如,如果您的输入是
test
dup
dup
one
two
one
three
one
test
five
M-x delete-duplicate-lines
会成功的
test
dup
one
two
three
five
您可以选择通过在其前面加上通用参数 ( C-u
) 来向后搜索。结果将是
dup
two
three
one
test
five
归功于emacsredux.com 。
其他回旋处选项,不给出完全相同的结果,可通过 Eshell 获得:
sort -u
; 不保持原件的相对顺序uniq
; 更糟糕的是,它需要对其输入进行排序将此代码放入您的 .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))))))
用法:
M-x uniq-lines
在linux中,选择区域,然后输入
M-| uniq <RETURN>
没有重复的结果在新缓冲区中。
(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))))))
替代:
\n
(UNIX 样式)。根据您的情况,这可能是一个好处或一个缺点。split-string
如果您以接受字符而不是正则表达式的方式重新实现,您可以让它更好一点(更快) 。稍长一些,但也许是更有效的变体:
(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))))))
其他方式: