地域内の行でGROUP BY + COUNT


7

リージョンで繰り返される個別の数を取得する最も簡単な方法は何ですか?

たとえば、

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

もらいたい

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

出力は同じ領域で作成できます(現在の選択を置き換えます)。

回答:


10

Linuxでは、私はMacを想定していますが、リージョンをuniqシェルコマンドにパイプして、ほぼ正確に必要なものを取得できます。

  1. 地域をマーク

  2. 行を並べ替える M-x sort-lines

  3. shell-command-on-regionプレフィックスキーで呼び出します:C-u M-|

  4. 入る uniq --count

バッファの内容は次のものに置き換えられます:

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

これをキーボードマクロなどでさらに自動化できますが、これで十分です。

編集:@philsが指摘しているように、Emacs関数ではなくシェルコマンドを使用してソートを行うことができます。この場合は、ステップ2をドロップし、ステップ4の場合は、のsort | uniq -c代わりにを入力しuniq -cます。


いいね!Mac uniqでは-cカウントを前に付けるオプションがあり、を使用する前にソートする必要はないと思いますuniq。(また、OPはバッファ全体ではなく、リージョンの処理を要求しました。)
コンスタンティン

ありがとう。Linuxの-c--count同義語であり、そしてあなたがソートする必要がありますか、多分Mac版は異なるデフォルトを使用しています。ステップ1を修正します!
タイラー、

私はただssh走っている箱に入りましたUbuntu 14.04.1 LTS:それでも私にとってソートは必要ありません。
コンスタンティン

1
タイラー:C-u M-| sort | uniq -c
phils 2014

1
ああ。コメントを編集するのが遅すぎます。「@rsenna:あなたが質問を投げかけたのはあなたです。あなたのために機能したことを知って嬉しく思います(評判ポイントは気にしません。+ 1に感謝しますが、私は完全に同意します私の答えは「最も簡単な方法」を与えないこと。) "
コンスタンティン

5

ここには3つのタスクがあります。

  1. 重複することなく、リージョン内の行のリストを取得します。
  2. このリストの各行について、元のリージョンで発生した回数をカウントし、この情報を収集します。
  3. 概要を挿入します。

 

(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)))

私は知りませんでしたしhow-manydelete-duplicate-lines存在していませんでした。英語の単語をハイフンでつなぐだけで、Emacsが何をすべきか知っているように見えることもあります。の組み込みEmacsバージョンuniqもあると思いますが、見つかりませんでした。
タイラー

2
これは非常に良い答えです。また、外部コマンドに依存しないため、Windowsでも機能します。
rsenna 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.