Emacs中文本的惯用批处理?

hat*_*rix 11 emacs elisp

在Python中,你可能会做类似的事情

fout = open('out','w')
fin = open('in')
for line in fin:
    fout.write(process(line)+"\n")
fin.close()
fout.close()
Run Code Online (Sandbox Code Playgroud)

(我认为它在许多其他语言中也会类似).在Emacs Lisp中,你会做类似的事吗?

(find-file 'out')
(setq fout (current-buffer)
(find-file 'in')
(setq fin (current-buffer)
(while moreLines
 (setq begin (point))
 (move-end-of-line 1)
 (setq line (buffer-substring-no-properties begin (point))
 ;; maybe
 (print (process line) fout)
 ;; or
 (save-excursion 
  (set-buffer fout)
  (insert (process line)))
 (setq moreLines (= 0 (forward-line 1))))
(kill-buffer fin)
(kill-buffer fout)
Run Code Online (Sandbox Code Playgroud)

我从Emacs Lisp获得灵感(和代码):逐行处理文件.或者我应该尝试完全不同的东西?以及如何""从print语句中删除?

Tre*_*son 33

如果你真正想要的批量处理stdin,并将结果发送给stdout,你可以使用--script命令行选项来Emacs,它将使你写的代码,它读出stdin和写入stdoutstderr.

这是一个示例程序cat,除了它反转每一行:

#!/usr/local/bin/emacs --script
;;-*- mode: emacs-lisp;-*-

(defun process (string)
  "just reverse the string"
  (concat (nreverse (string-to-list string))))

(condition-case nil
    (let (line)
      ;; commented out b/c not relevant for `cat`, but potentially useful
      ;; (princ "argv is ")
      ;; (princ argv)
      ;; (princ "\n")
      ;; (princ "command-line-args is" )
      ;; (princ command-line-args)
      ;; (princ "\n")

      (while (setq line (read-from-minibuffer ""))
        (princ (process line))
        (princ "\n")))
  (error nil))
Run Code Online (Sandbox Code Playgroud)

现在,如果你有一个名为stuff.txt包含的文件

abcd
1234
xyz
Run Code Online (Sandbox Code Playgroud)

你调用了上面写的shell脚本(假设它被命名rcat):

rcat < stuff.txt
Run Code Online (Sandbox Code Playgroud)

你会看到以下打印到标准输出:

dcba
4321
zyx
Run Code Online (Sandbox Code Playgroud)

因此,与流行的看法相反,您实际上可以进行批处理文件处理,stdin而不是实际上必须立即读取整个文件.

  • 交叉引用以下答案,其中显示了如何将其他命令行参数传递给Emacs脚本:http://stackoverflow.com/questions/6238331/emacs-shell-scripts-how-to-put-initial-options-into -The脚本#6259330 (4认同)

Sea*_*ean 5

这就是我想出来的.对我来说看起来更惯用:

(with-temp-buffer
  (let ((dest-buffer (current-buffer)))
    (with-temp-buffer
      (insert-file-contents "/path/to/source/file")
      (while (search-forward-regexp ".*\n\\|.+" nil t)
        (let ((line (match-string 0)))
          (with-current-buffer dest-buffer
            (insert (process line)))))))
  (write-file "/path/to/dest/file" nil))
Run Code Online (Sandbox Code Playgroud)