NHÓM THEO + COUNT trên các dòng trong một khu vực


7

Cách đơn giản nhất để có được số lượng khác biệt lặp lại trong một khu vực là gì?

Ví dụ: từ

THIS IS LINE A
THIS IS LINE A
THIS IS LINE A
THIS IS LINE B
THIS IS LINE B
THIS IS LINE C

tôi muốn có được

THIS IS LINE A    3
THIS IS LINE B    2
THIS IS LINE C    1

Đầu ra có thể được thực hiện trên cùng một khu vực (thay thế lựa chọn hiện tại).

Câu trả lời:


10

Trên Linux, và tôi giả sử Mac, bạn có thể dẫn vùng qua uniqlệnh shell để có được gần như chính xác những gì bạn muốn.

  1. Đánh dấu khu vực

  2. Sắp xếp các dòng với M-x sort-lines

  3. Gọi shell-command-on-regionbằng phím tiền tố:C-u M-|

  4. Đi vào uniq --count

Nội dung của bộ đệm sẽ được thay thế bằng:

  3 THIS IS LINE A
  2 THIS IS LINE B
  1 THIS IS LINE C

Bạn có thể tự động hóa thêm với macro bàn phím, v.v., nhưng điều này có thể đủ tốt.

EDIT: như @phils chỉ ra, bạn có thể thực hiện sắp xếp bằng lệnh shell thay vì bằng hàm Emacs. Trong trường hợp này, thả bước 2 và nhập bước 4 sort | uniq -cthay vì chỉ uniq -c.


Đẹp! Trên máy Mac uniq-ctùy chọn để thêm số lượng và tôi không nghĩ bạn cần sắp xếp trước khi sử dụng uniq. (Ngoài ra, OP đã yêu cầu xử lý vùng , chứ không phải toàn bộ bộ đệm.)
Constantine

Cảm ơn. Trên Linux -c--countlà từ đồng nghĩa, và bạn cần phải sắp xếp, nhưng có thể phiên bản Mac sử dụng các giá trị mặc định khác nhau. Tôi sẽ sửa bước 1!
Tyler

Tôi chỉ sshvào một hộp đang chạy Ubuntu 14.04.1 LTS: vẫn không cần sắp xếp cho tôi.
Constantine

1
Tyler:C-u M-| sort | uniq -c
phils

1
Ừ Tôi quá chậm để chỉnh sửa ý kiến. Đây là những gì tôi dự định nói: "@rsenna: Bạn là người đặt ra câu hỏi; rất vui khi biết rằng nó hiệu quả với bạn. (Tôi không quan tâm đến điểm danh tiếng; Tôi đánh giá cao +1, nhưng tôi hoàn toàn đồng ý rằng câu trả lời của tôi không đưa ra "cách đơn giản nhất".) "
Constantine

5

Tôi thấy ba nhiệm vụ ở đây:

  1. Lấy danh sách các dòng trong một khu vực, không trùng lặp.
  2. Đối với mỗi dòng trong danh sách này, hãy đếm số lần xảy ra trong khu vực ban đầu và thu thập thông tin này.
  3. Chèn tóm tắt.

 

(defun uniqify-lines (beg end)
  "Return a list of lines in a region (without duplicates). Omit empty lines."
  (let ((text (buffer-substring beg end)))
    (with-temp-buffer
      (insert text)
      (delete-duplicate-lines (point-min) (point-max))
      (split-string (buffer-string) "\n" t))))

(defun count-duplicates (beg end)
  "Count duplicate lines in a region. Returns a list of the
    form ((line . count) ...)."
  (mapcar (lambda (str)
            (cons str (how-many (regexp-quote str) beg end)))
          (uniqify-lines beg end)))

(defun insert-line-stats (beg end)
  "Remove duplicate lines in the region. Append the number of
    occurences to each line in the result. Replaces current region."
  (interactive "r")
  (let ((stats (count-duplicates beg end)))
    (kill-region beg end)
    (mapc (lambda (line)
            (insert (format "%s %d\n" (car line) (cdr line))))
          stats)))

Tôi không biết how-manyhoặc delete-duplicate-linestồn tại - đôi khi có vẻ như bạn chỉ có thể xâu chuỗi các từ tiếng Anh cùng với dấu gạch nối và Emacs biết phải làm gì! Tôi nghi ngờ cũng có một phiên bản Emacs tích uniqhợp, nhưng tôi đã không tìm thấy nó.
Tyler

2
Đây là một câu trả lời rất tốt. Và vì nó không phụ thuộc vào bất kỳ lệnh bên ngoài nào, nó cũng hoạt động trong Windows.
rsenna
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.