Emacs elisp实现“uniq-c”Unix命令来计算唯一行数

Emacs elisp实现“uniq-c”Unix命令来计算唯一行数,emacs,uniq,Emacs,Uniq,如果区域中存在数据,请执行以下操作: flower park flower stone flower stone stone flower 然后可以按频率或项目对这些数据进行排序 它类似于bash中的uniq-c 那为什么不使用uniq-c呢 高亮显示区域后,M-| sort | uniq-c将在当前区域上运行该命令。结果将显示在minibuffer中,并将在*Messages*buffer中列出。添加前缀arg将把结果插入当前缓冲区 它类似于bash中的uniq-c 那为什么不使用uniq-c

如果区域中存在数据,请执行以下操作:

flower park flower stone flower stone stone flower 然后可以按频率或项目对这些数据进行排序

它类似于bash中的uniq-c

那为什么不使用uniq-c呢

高亮显示区域后,M-| sort | uniq-c将在当前区域上运行该命令。结果将显示在minibuffer中,并将在*Messages*buffer中列出。添加前缀arg将把结果插入当前缓冲区

它类似于bash中的uniq-c

那为什么不使用uniq-c呢


高亮显示区域后,M-| sort | uniq-c将在当前区域上运行该命令。结果将显示在minibuffer中,并将在*Messages*buffer中列出。添加前缀arg将把结果插入当前缓冲区。

我认为一种常见的方法是对字符串进行散列,然后打印内容。这种方法可以在emacs中轻松实现

;; See the emacs manual for creating a hash table test
;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Defining-Hash.html
(defun case-fold-string= (a b)
  (eq t (compare-strings a nil nil b nil nil t)))
(defun case-fold-string-hash (a)
  (sxhash (upcase a)))

(define-hash-table-test 'case-fold
  'case-fold-string= 'case-fold-string-hash)

(defun uniq (beg end)
  "Print counts of strings in region."
  (interactive "r")
  (let ((h (make-hash-table :test 'case-fold))
        (lst (split-string (buffer-substring-no-properties beg end) "\n"
                           'omit-nulls " "))
        (output-func (if current-prefix-arg 'insert 'princ)))
    (dolist (str lst) 
      (puthash str (1+ (gethash str h 0)) h))
    (maphash (lambda (key val)
               (apply output-func (list (format "%d: %s\n" val key))))
             h)))
选择该文本时输出

4: flower
1: park
3: stone

我认为一种常见的方法是将字符串散列,然后打印内容。这种方法可以在emacs中轻松实现

;; See the emacs manual for creating a hash table test
;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Defining-Hash.html
(defun case-fold-string= (a b)
  (eq t (compare-strings a nil nil b nil nil t)))
(defun case-fold-string-hash (a)
  (sxhash (upcase a)))

(define-hash-table-test 'case-fold
  'case-fold-string= 'case-fold-string-hash)

(defun uniq (beg end)
  "Print counts of strings in region."
  (interactive "r")
  (let ((h (make-hash-table :test 'case-fold))
        (lst (split-string (buffer-substring-no-properties beg end) "\n"
                           'omit-nulls " "))
        (output-func (if current-prefix-arg 'insert 'princ)))
    (dolist (str lst) 
      (puthash str (1+ (gethash str h 0)) h))
    (maphash (lambda (key val)
               (apply output-func (list (format "%d: %s\n" val key))))
             h)))
选择该文本时输出

4: flower
1: park
3: stone

我想有很多方法可以解决这个问题。这里有一个相当简单的方法:

defun uniq-c开始-结束 像M-| uniq-c 交互式r 让源电流缓冲器 dest生成新缓冲区*uniq-c* 案例折叠搜索无 设置缓冲区dest 插入缓冲区子字符串源开始-结束 转到字符点最小值 而让*行缓冲子字符串行开始位置 线端位置 模式concat^regexp报价行$ 计数与模式点最大值匹配 插入格式%d计数 前线1 齐平线条图案 不是eobp 跳转到缓冲区dest
我想有很多方法可以解决这个问题。这里有一个相当简单的方法:

defun uniq-c开始-结束 像M-| uniq-c 交互式r 让源电流缓冲器 dest生成新缓冲区*uniq-c* 案例折叠搜索无 设置缓冲区dest 插入缓冲区子字符串源开始-结束 转到字符点最小值 而让*行缓冲子字符串行开始位置 线端位置 模式concat^regexp报价行$ 计数与模式点最大值匹配 插入格式%d计数 前线1 齐平线条图案 不是eobp 跳转到缓冲区dest
否。计数匹配项为单个项目计数。uniq-c给出列表编号中多个项目的计数。计数匹配项为单个项目计数。uniq-c为列表中的多个项目提供计数uniq-c在某些环境中本机不可用。这就是问题的全部原因。uniq-c在某些环境中本机不可用。这就是问题的全部原因,尤其是因为它完全基于regexp,没有任何有用的理由,所以这不是一个非常有效的解决方案;但这应该是一个易于阅读/理解的过程。此外,请注意,与jenesaisquoi基于哈希的方法相比,此过程的复杂性为^2。尤其是由于它完全基于regexp,没有任何有用的原因,因此这将不是一个非常有效的解决方案;但这应该是一个易于阅读/理解的过程。此外,请注意,此过程的复杂性为^2,而jenesaisquoi基于哈希的方法的复杂性为^2。这是一个又好又快的过程。不确定您是否希望忽略空值和行修剪行为,但是?我想maphash序列是未定义的?@phils对,如果需要按键/值排序,我会在maphash函数中放入类似push-cons-val-key-result的内容,并将cl排序结果“>:key”car afterwardsNice和fast放在后面。不确定您是否希望忽略空值和行修剪行为,但是?我想maphash序列是未定义的?@phils是的,如果需要按键/值排序,我会在maphash函数中放入类似push-cons-val-key-result的内容,然后在maphash函数中放入cl-sort-results'>:key'car