【问题标题】:Read from a file into a Emacs lisp list从文件读入 Emacs lisp 列表
【发布时间】:2013-12-23 16:15:40
【问题描述】:

我有以下文件data.txt

A
B
C
D

我想把这个文件的内容读入一个 Lisp list,比如

(defun read-list-from-file (fn)
  (interactive)
  (list "A" "B" "C" "D"))

(defun my-read ()
  (interactive)
  (let (( mylist (read-list-from-file "data.txt")))
    (print mylist t)))

如何修改read-list-from-file 使其返回相同的列表,而是从作为输入参数fn 给出的文件中读取。文件中的每一行都应该是列表中的一个单独的项目..

【问题讨论】:

    标签: emacs elisp


    【解决方案1】:

    这段代码:

    (with-current-buffer
        (find-file-noselect "~/data.txt")
      (split-string
       (save-restriction
         (widen)
         (buffer-substring-no-properties
          (point-min)
          (point-max)))
       "\n" t))
    

    更新:

    这是一个带有insert-file-contents的版本:

    (defun slurp (f)
      (with-temp-buffer
        (insert-file-contents f)
        (buffer-substring-no-properties
           (point-min)
           (point-max))))
    
    (split-string
     (slurp "~/data.txt") "\n" t)
    

    【讨论】:

    • 请注意,如果您有一个访问data.txt 的开放缓冲区,并且该缓冲区被缩小,则此函数可能不会返回它应该返回的所有内容。你应该把对split-string 的调用包装在(save-restriction (widen) ...) 中。
    • 谢谢,@Sean。已更新。
    • 使用with-temp-bufferinsert-file-contents 而不是with-current-bufferfind-file-noselect 以避免留下缓冲区。
    • buffer-string 也使这变得更容易。您不必担心属性删除,因为您刚刚读取的文件上可能没有任何属性,或者您可以使用 insert-file-contents-literally
    【解决方案2】:

    比创建临时缓冲区更容易的是使用f 文件操作库的f-read 函数返回文件的文本内容(默认编码为UTF-8)。 f 是您需要从 MELPA 安装的第三方,请阅读 Xah Lee's 教程了解如何使用 Emacs 包管理系统。然后您可以使用split-strings 字符串操作库的s-split(这是对前一个函数的简单包装):

    (s-split "\n" (f-read "~/data.txt") t) ; ("A" "B" "C" "D")
    

    注意: s-split 的第三个参数设置为 t 省略空字符串。您可以使用s-lines,但由于*nix 系统上的文本文件通常包含尾随换行符,因此返回的列表将是("A" "B" "C" "D" "")。您可以使用 dash 列表操作库的 butlast 函数删除最后一个元素,但这在 O(n) 中有效,因此可能坚持使用 s-split,除非您希望在列表中保留空行。

    【讨论】:

    • 很好的答案,我已经使用 s 进行字符串操作,并使用 dash 进行其他所有操作,很高兴知道文件操作也有一个不错的 f。
    • FWIW, f-read 使用与@abo-abo 的slurp 基本相同的方法(即创建一个临时缓冲区):github.com/rejeep/f.el/blob/master/f.el#L207 不过它还有其他优点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多