CSVファイルとか、XMLのタグ抽出したりとかで、何かと必要になることが多いのが重複行の削除。
xyzzy では C-x # uniq して、外部の uniq.exe を使うのがデフォの様子。
だけど、これぐらいの日常タスクなら xyzzy だけでやりたいと思ったから適当に書いといた。
- 範囲はリージョンで指定する
- 連続して重複していようが、ばらけていようが、2回以上の出現は重複とみなす
- ならびは元のデータに合わせる
- 大文字小文字区別 あり uniq-line-region
- 大文字小文字区別 なし uniq-line-region-case-insensitive
下のようになる。
(元データ) uniq-line-region uniq-line-region-case-insensitive ---------- ---------------- --------------------------------- AAA AAA AAA ccc ccc ccc CCC CCC xxx aaa aaa BBB AAA xxx aaa BBB xxx bbb BBB bbb ccc aaa bbb aaa aaa
(defun uniq-line-region (from to &optional case-insensitive) "重複行を削除する。case-insensitive を省略するか nil の場合は、大文字小文字の区別をする。 non-nil のときは大文字小文字を区別しない。" (interactive "*r") (save-excursion (save-restriction (narrow-to-region from to) (goto-char (point-min)) (let (l) (loop (let ((s (buffer-substring (progn (goto-eol) (point)) (progn (goto-bol) (point))))) (unless (member s l :test (if case-insensitive #'string-equal #'string=)) (setq l (cons s l))) (unless (forward-line 1) (return)))) (delete-region from to) (with-output-to-selected-buffer (map nil #'(lambda (x) (format t "~A~%" x)) (nreverse l))))))) (defun uniq-line-region-case-insensitive (from to) "重複行を削除する。大文字小文字を区別しない。" (interactive "*r") (uniq-line-region from to t))
似たようなタスクとして、リージョンをソートしたいときは下記が参考になる。
0 コメント :
コメントを投稿