在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和写入stdout和stderr.
这是一个示例程序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而不是实际上必须立即读取整个文件.
这就是我想出来的.对我来说看起来更惯用:
(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)