EMACS Lisp程序员如何读取文本文件以进行非编辑?

时间:2015-05-29 17:01:02

标签: file-io emacs elisp

EMACS Lisp程序员做什么,当他们想要写一些大致相当于......

的东西时
for line in open("foo.txt", "r", encoding="utf-8").readlines():
    ...(split on ws and call a fn, or whatever)...

...

当我查看EMACS lisp帮助时,我看到了将文件打开到文本编辑缓冲区的功能 - 这不是我想要的。我想我可以编写函数来访问文件的行,但如果我这样做,我就不希望用户看到它,而且,从文本处理看起来效率不高观点出发

2 个答案:

答案 0 :(得分:9)

我认为原始Python代码的更直接的翻译如下:

(with-temp-buffer
  (insert-file-contents "foo.txt")
  (while (search-forward-regexp "\\(.*\\)\n?" nil t)
    ; do something with this line in (match-string 1)
    ))

我认为with-temp-buffer / insert-file-contents通常比with-current-buffer / find-file-noselect更受欢迎,因为前者保证您使用整个新副本文件内容。使用后一种结构,如果你碰巧已经有一个访问目标文件的缓冲区,那么find-file-noselect就会返回该缓冲区,所以如果缩小了该缓冲区,你只会看到该文件的那一部分当你处理它时。

请注意,逐行处理文件可能更方便。例如,这是一个表达式,它返回文件中所有连续数字序列的列表:

(with-temp-buffer
  (insert-file-contents "foo.txt")
  (loop while (search-forward-regexp "[0-9]+" nil t)
        collect (match-string 0)))

(require 'cl)首先引入loop宏。

答案 1 :(得分:4)

  1. 是的,您想要做的事情:在缓冲区中访问该文件,然后对该缓冲区中的文本进行操作。

  2. 必须显示缓冲区,即用户无需查看。

  3. 至于效率:在缓冲区中操作文本通常是操作文本的有效方式。

  4. 您可以通过多种方式访问​​缓冲区中的文件。您可能希望使用现有的文件缓冲区,具体取决于用例。也就是说,如果文件已经打开"在Emacs中你可能想要使用它的缓冲区。

    或者您可能想要忽略已经打开的任何现有文件缓冲区"文件,并将文件重新读入新缓冲区。为此,正如@Sean所提到的,您可以将insert-file-contents与您创建的缓冲区一起使用。您可以使用with-temp-buffergenerate-new-buffer创建缓冲区,具体取决于您希望/需要使用的内容。

    如果您确实要重用已经访问该文件的缓冲区,您可以测试它是否已在内存中修改,是否缩小等,并执行适合您的用例的任何操作。您可以使用函数find-buffer-visiting检查是否已有缓冲区访问该文件(使用任何路径/文件名)。

    要访问该文件,利用访问它的任何现有缓冲区,您可以使用find-file-noselect。该函数返回访问文件的缓冲区,因此您可以将该缓冲区作为第一个参数传递给with-current-buffer。这是一个简单的例子。

    (with-current-buffer (let ((enable-local-variables  ())) (find-file-noselect file))
      ;; Do some stuff with the text in the buffer.
      ;; Optionally save the buffer back to the file.
      )
    

    enable-local-variablesnil的绑定是次要优化,适用于您不需要打扰缓冲区局部变量的常见情况。)