我使用OpenMCL达尔文,我想这样做:如何遍历Common Lisp中的目录?
(loop for f in (directory "somedir")
collect (some-per-file-processing f))
但我不能让directory
返回以外的任何其他NIL
,我似乎无法找到任何网上很好的解释(除“每个系统的不同之外”)。
任何指针?
我使用OpenMCL达尔文,我想这样做:如何遍历Common Lisp中的目录?
(loop for f in (directory "somedir")
collect (some-per-file-processing f))
但我不能让directory
返回以外的任何其他NIL
,我似乎无法找到任何网上很好的解释(除“每个系统的不同之外”)。
任何指针?
您的路径名规范是否包含通配符? Common Lisp中的路径名的东西是有点难以把握在第一 - 至少对我来说是......正如CLHS状态上directory
功能:
如果pathspec不是野外, 结果列表将包含两种 零个或一个元素。
为了让您的路径包括通配符,你可以尝试化妆路径功能,如
(directory (make-pathname :directory '(:absolute "srv" "hunchentoot") :name :wild :type "lisp"))
甚至
(directory (make-pathname :directory '(:absolute "srv" "hunchentoot") :name :wild :type :wild))
我发现CL-FAD库有很大的帮助用于处理路径名和文件系统。特别是,其功能list-directory
可能比普通标准directory
功能更易于使用。
基本上有两种方式来指定路径名:
字符串显然取决于平台:Unix的语法与Windows的语法例子。
"/Users/foo/bar.text" is a valid pathname
"/Users/foo/*/foo.*" is a valid pathname with two wildcards
您可以从字符串创建路径对象:
? (pathname "/Users/bar/foo.text")
#P"/Users/bar/foo.text"
的#P上述保证路径名对象(而不是字符串)创建,当你读了回去。
? #P"/Users/bar/foo.text"
#P"/Users/bar/foo.text"
因此,内部Common Lisp与路径名对象一起工作,但它允许您使用普通字符串,并根据需要为它们生成路径名对象。
当Common Lisp发现没有指定所有组件的路径名称(例如该目录缺失)时,它会从路径名对象填充组件,该对象是variabel * DEFAULT-PATHNAME-DEFAULTS *的值。
使用功能描述你可以看看路径名称(这里Clozure CL)的组成部分:
? (describe (pathname "/Users/bar/*.text"))
#P"/Users/bar/*.text"
Type: PATHNAME
Class: #<BUILT-IN-CLASS PATHNAME>
TYPE: (PATHNAME . #<CCL::CLASS-WRAPPER PATHNAME #x3000401D03BD>)
%PATHNAME-DIRECTORY: (:ABSOLUTE "Users" "bar")
%PATHNAME-NAME: :WILD
%PATHNAME-TYPE: "text"
%PHYSICAL-PATHNAME-VERSION: :NEWEST
%PHYSICAL-PATHNAME-DEVICE: NIL
MAKE-PATHNAME是函数,它需要几个关键字参数来指定组件。
有时它也是创建基于现有的一个新的路径有用:
(make-pathname :name "foo" :defaults (pathname "/Users/bar/baz.text"))
如果您使用目录它使用一个带有通配符路径是非常有用的。 DIRECTORY然后将返回匹配路径名的列表。名称'DIRECTORY'有点误导,因为DIRECTORY没有列出目录的内容,但列出了通常使用通配符的路径名的匹配路径名。通配符可以匹配组件中的一系列字符,如/foo/s*c/list*.l*“。还有一个通配符**,用于匹配/ foo/**目录等级的部分/test.lisp,其中的所有文件相匹配test.lisp目录foo和其子目录下。
(directory "/Users/foo/Lisp/**/*.lisp")
以上应返回“/用户/富/ Lisp语言/”和所有的一切“口齿不清”的文件列表其子目录
要在单一目录使用返回.c文件:
(directory "/Users/foo/c/src/*.c")
注意这种可怕CTORY返回一个路径名对象列表(不是一个字符串列表)。
? (directory (make-pathname
:name "md5"
:type :wild
:directory '(:absolute "Lisp" "cl-http" "cl-http-342" "server")))
(#P"/Lisp/cl-http/cl-http-342/server/md5.lisp"
#P"/Lisp/cl-http/cl-http-342/server/md5.xfasl")
上面使用由MAKE-PATHNAME创建的路径名对象。它会返回所有匹配/Lisp/cl-http/cl-http-342/server/md5.*的文件。
这是一样的:
(directory "/Lisp/cl-http/cl-http-342/server/md5.*")
其是较短的,但依赖于Unix的路径名的语法。
+1 LISP中路径名的很好的总结,非常有帮助。 – Justicle 2009-09-10 23:08:54
实现目录列表的现代Common Lisp库是IOLIB。
它的工作原理是这样的:
CL-USER> (iolib.os:list-directory "/etc/apt")
(#/p/"trusted.gpg~" #/p/"secring.gpg" #/p/"trustdb.gpg" #/p/"sources.list"
#/p/"sources.list~" #/p/"apt-file.conf" #/p/"apt.conf.d" #/p/"trusted.gpg"
#/p/"sources.list.d")
注意,不需要尾随斜线或通配符。它非常健壮,甚至可以用错误编码的unicode字符处理文件名。
的差异相比,CL-FAD:
我会添加一个适用于我的示例,代码片段。我使用osicat(类似于cl-fad)和str。
编辑:也与uiop:directory-files
。 STR:含有?可以用search
完成。
;; searching for "ref".
(setf *data-directory* "~/books/lisp")
(remove-if-not (lambda (it)
(str:contains? "ref" (namestring it)))
(osicat:list-directory *data-directory*))
回报
(#P"~/books/lisp/common-lisp-quick-reference-clqr-a4-booklet-all.pdf"
#P"~/books/lisp/common-lisp-quick-reference-clqr-a4-consec.pdf"
#P"~/books/lisp/commonLisp-interactive-approach-reference-buffalo.pdf")
它当然可以提高我的正确使用通配符。但是这是你可以使用一个片段现在:)
参考文献:
是的工作对我来说 - (目录 “路径”)返回NIL,其中(目录“路径名/*.*”)给了我预期的结果。 – Justicle 2009-09-10 07:14:12
您只需要名称中包含点的文件? – Svante 2009-09-10 07:16:03
怪怪的?我实际上是在.h和.cpp文件之后,但“路径名/ *”返回NIL。 – Justicle 2009-09-10 07:28:42