使用elisp处理文本

kon*_*onr 6 lisp emacs awk elisp

自从我转换为Emacs教会以来,我一直在尝试从内部做所有事情,我想知道如何快速高效地进行文本处理.

作为一个例子,让我们在几分钟前在org-mode上编辑我正在编辑的列表.

** Diego: b QI
** bruno-gil: b QI
** Koma: jo
** um: rsrs pr0n
** FelipeAugusto: esp
** GustavoPupo: pinto tr etc
** GP: lit gtk
** Alan: jo mil pc
** Jost: b hq jo 1997
** Herbert: b rsrs pr0n
** Andre: maia mil pseudo
** Rodrigo: c
** caue: b rsrs 7arte pseudo
** kenny: cri gif
** daniel: gtk mu pr0n rsrs b
** tony: an 1997 esp
** Vitor: b jo mimimi
** raphael: b rpg 7arte
** Luca: b lit gnu pc prog mmu 7arte 1997
** LZZ: an qt
** William: b an jo pc 1997
** Epic: gtk
** Aldo: b pseudo pol mil fur
** GustavoKyon: an gtk
** CarlosIsaksen : an hq jo 7arte gtk 1997
** Peter: pseudo pol mil est 1997 gtk lit lang
** leandro: b jo cb
** frederico: 7arte lit gtk
** rol: b an pseudo mimimi 7arte
** mathias: jo lit
** henrique: 1997 h gtk qt
** eumané: an qt
** walrus: cri de
** FilipePinheiro: lit pseudo
** Igor: pseudo b
** Erick: b jo rpg q 1997 gtk
** Gabriel: pr0n rsrs qt
** george: clo mimimi
** anão: hq jo 1997 rsrs clô b
** jeff: 7arte gtk
** davidatenas:  an 7arte 1997 esp qt
** HHahaah: b 
** Eduardo: b

它是与标签关联的名称列表,我想获得与名称关联的标签列表.

在bash中,我首先用单引号回显整个粘贴的东西,然后将其传递给awk,循环遍历每一行并将每个部分添加到正确的临时变量中,然后将其弄乱,直到它像我想要的那样.

echo '** Diego: b QI
** bruno-gil: b QI
** Koma: jo
** um: rsrs pr0n
** FelipeAugusto: esp
** GustavoPupo: pinto, tr etc
** GP: lit gtk
** Alan: jo mil pc
** Jost: b hq jo 1997
** Herbert: b rsrs pr0n
** Andre: maia mil pseudo
** Rodrigo: c
** caue: b rsrs 7arte pseudo
** kenny: cri gif
** daniel: gtk mu pr0n rsrs b
** tony: an 1997 esp
** Vitor: b jo mimimi
** raphael: b rpg 7arte
** Luca: b lit gnu pc prog mmu 7arte 1997
** LZZ: an qt
** William: b an jo pc 1997
** Epic: gtk
** Aldo: b pseudo pol mil fur
** GustavoKyon: an gtk
** CarlosIsaksen : an hq jo 7arte gtk 1997
** Peter: pseudo pol mil est 1997 gtk lit lang
** leandro: b jo cb
** frederico: 7arte lit gtk
** rol: b an pseudo mimimi 7arte
** mathias: jo lit
** henrique: 1997 h gtk qt
** eumané: an qt
** walrus: cri de
** FilipePinheiro: lit pseudo
** Igor: pseudo b
** Erick: b jo rpg q 1997 gtk
** Gabriel: pr0n rsrs qt
** george: clo mimimi
** anão: hq jo 1997 rsrs clô b
** jeff: 7arte gtk
** davidatenas:  an 7arte 1997 esp qt
** HHahaah: b
** Eduardo: b
' | awk '{sub(":","");for (i=3;i<=NF;i++) members[$i] = members[$i] " " $2}; END{for (j in members) print j ": " members[j]}' | sort

......和TA-DA!预期的输出不到2分钟,以直观和渐进的方式完成.你能告诉我如何在elisp中做这样的事情,最好是在emacs缓冲区,优雅和简单吗?

谢谢!

hax*_*ney 7

我要做的第一件事就是利用org-mode标签支持.代替

** Diego: b QI
Run Code Online (Sandbox Code Playgroud)

你将会拥有

** Diego                          :b:QI:
Run Code Online (Sandbox Code Playgroud)

org-mode被识别为标签"b"和"QI".

要将当前格式转换为标准org-mode格式,可以使用以下内容(假设带有源的缓冲区称为"asdf")

(with-current-buffer "asdf"
  (beginning-of-buffer)
  (replace-string " " ":")
  (beginning-of-buffer)
  (replace-string "**:" "** ")
  (beginning-of-buffer)
  (replace-string "::" " :")
  (beginning-of-buffer)
  (replace-string "\n" ":\n")
  (org-set-tags-command t t))
Run Code Online (Sandbox Code Playgroud)

这不是很好或有效,但它完成了工作.

之后,您可以使用以下命令从shell脚本生成具有所需格式的缓冲区:

(let ((results (get-buffer-create "results"))
      tags)
  (with-current-buffer "asdf"
    (beginning-of-buffer)
    (while (org-on-heading-p)
      (mapc '(lambda (item) (when item (add-to-list 'tags item))) (org-get-local-tags))
      (outline-next-visible-heading 1)))
  (setq tags (sort tags 'string<))
  (with-current-buffer results
    (erase-buffer)
    (mapc '(lambda (item)
             (insert (format "%s: %s\n"
                             item
                             (with-current-buffer "asdf"
                               (org-map-entries '(substring-no-properties (org-get-heading t)) item)))))
          tags)
    (beginning-of-buffer)
    (replace-regexp "[()]" "")))
Run Code Online (Sandbox Code Playgroud)

这会将结果放在一个名为"results"的缓冲区中,如果它尚不存在则创建它.基本上,它收集缓冲区"asdf"中的所有标签,对它们进行排序,然后循环遍历每个标签,并在"asdf"中搜索带有该标签的每个标题,并将其插入"结果".

通过一些清理,这可以成为一个功能; 基本上只是用参数替换"asdf"和"results".如果你需要那样做,我可以做到.


Bry*_*ley 5

有一个函数shell-command-on-region就像它所说的那样.您可以突出显示某个区域,执行M- |,键入shell命令的名称,然后将数据传送到该命令.给它一个参数,并用命令的结果替换该区域.

对于一个简单的例子,突出显示一个区域,输入'Cu 0 M- | wc'(control-u,zero,meta-pipe,然后是'wc'),该区域将被该区域的字符数,字数和行数替换.

您可以做的另一件事是弄清楚如何操作一行,使其成为宏,然后重复运行宏.例如,'Cx(Cs foo Cg bar Cx)'将搜索单词"foo",然后键入单词"bar",将其更改为"foobar".然后,您可以执行'Cu Cx e',它将继续运行宏,直到找不到更多的"foo".


kon*_*onr 0

这是我的第二次尝试。我写了一个小宏和一些函数来处理这些数据。

\n\n
\n(defun better-numberp (s)\n (字符串匹配 "^ *[0-9.,]* *$" s))\n\n(defmacro awk-like (&rest args)\n (let ((arg (car (最后一个参数)))\n (调用 (mapcar #\'(lambda (l)\n (cond\n ((numberp (first l))) (cons `(lambda (f) (等于 % r ,(第一个 l))) (剩余的 l)))\n ((stringp (第一个 l)) (cons `(lambda (f) (字符串匹配 ,(第一个 l) %)) (剩余的 l))) \n (tl)))\n (butlast args))))\n `(mapcar #\'(lambda (%%)\n (let ((%r 0)))\n (mapcar\n #\' (lambda (l)\n (setq %r (1+ %r))\n (let ((% l))\n (dolist (tipo \',calls)\n (progn\n (setq % (cond \n ((funcall (第一个类型) %) (eval (cadr 类型))) (t %)))\n (set (intern (格式 "%%%d" %r)) %))) %)) %%)))\n (mapcar #\'(lambda (y) (分割字符串 y " " t))\n (分割字符串 ,arg "\\n" t)))))\n\n (defun hash-to-list (hashtable)\n “返回表示哈希表的列表。”\n (let (mylist)\n (maphash (lambda (kk vv)) (setq mylist (cons (list kk vv) mylist) ))) hashtable)\n mylist\n )\n )\n\n(defun append-hash (键值哈希表)\n (let ((current (gethash key hashtable)))\n (puthash key \n ( cond\n ((null 当前) (列表值))\n ((listp 当前) (cons 值当前))\n (t 当前)) \n 哈希表)))\n\n
\n\n
\n(let ((foohash (make-hash-table :test \'equal)))\n (类似 awk\n (2 (replace-regexp-in-string ":" "" %))\n ( (lambda (f) (> %r 2)) (append-hash % %2 foohash))\n "** 迭戈: b QI\n** 布鲁诺-吉尔: b QI\n** Koma: jo\n ** um: rsrs pr0n\n** FelipeAugusto: esp\n** GustavoPupo: pinto tr 等\n** GP: lit gtk\n** Alan: jo mil pc\n** Jost: b hq jo 1997\ n** 赫伯特:b rsrs pr0n\n** 安德烈:maia mil 伪\n** 罗德里戈:c\n** 原因:b rsrs 7arte 伪\n** 肯尼:cri gif\n** 丹尼尔:gtk mu pr0n rsrs b\n** 托尼:an 1997 esp\n** Vitor:b jo mimimi\n** 拉斐尔:b rpg 7arte\n** 卢卡:b lit gnu pc prog mmu 7arte 1997\n** LZZ:一个 qt\n** William:b 一个 jo pc 1997\n** 史诗:gtk\n** Aldo:b 伪 pol mil 毛皮\n** GustavoKyon:一个 gtk\n** CarlosIsaksen:一个 hq jo 7arte gtk 1997\n** Peter:伪 pol mil est 1997 gtk lit lang\n** Leandro:b jo cb\n** frederico:7arte lit gtk\n** rol:b 伪 mimimi 7arte\n** mathias: jo lit\n** henrique:1997 h gtk qt\n** euman\xc3\xa9:an qt\n** 海象:cri de\n** FilipePinheiro:点亮伪\n** Igor:伪 b\n ** 埃里克:b jo rpg q 1997 gtk\n** 加布里埃尔:pr0n rsrs qt\n** 乔治:克洛米米米\n** an\xc3\xa3o:hq jo 1997 rsrs cl\xc3\xb4 b\n* * jeff: 7arte gtk\n** davidatenas: 7arte 1997 esp qt\n** HHahaah: b\n** Eduardo: b\n")\n (hash-to-list foohash))\n
\n