문제

저는 Darwin에서 OpenMCL을 사용하고 있으며 다음과 같은 작업을 수행하고 싶습니다.

(loop for f in (directory "somedir")
  collect (some-per-file-processing f))

하지만 난 얻을 수 없습니다 directory 이외의 것을 반환하려면 NIL, 온라인에서 좋은 설명을 찾을 수 없는 것 같습니다("시스템마다 다릅니다" 제외).

어떤 조언이 있습니까?

도움이 되었습니까?

해결책

PathName 사양에 와일드 카드가 포함되어 있습니까? Common Lisp의 PathName은 처음에는 이해하기가 다소 어렵습니다. 적어도 저에게는 ... CLHS 상태 directory 기능:

PathSpec이 거칠지 않은 경우 결과 목록에는 0 또는 하나의 요소가 포함됩니다.

PathName에 와일드 카드가 포함되도록하려면 Make-PathName 기능을 사용해 볼 수 있습니다.

(directory (make-pathname :directory '(:absolute "srv" "hunchentoot") :name :wild :type "lisp"))

또는

(directory (make-pathname :directory '(:absolute "srv" "hunchentoot") :name :wild :type :wild))

나는 찾았다 CL-FAD 라이브러리 PathNames 및 파일 시스템을 다루는 데 큰 도움이됩니다. 특히, 그것 list-directory 기능은 일반 표준보다 사용하기가 더 쉬울 수 있습니다. directory 기능.

다른 팁

기본적으로 경로 이름을 지정하는 방법에는 두 가지가 있습니다.

  • 문자열을 사용하여

문자열은 분명히 플랫폼에 따라 다릅니다.유닉스 구문과 유닉스 구문 비교예를 들어 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* 값인 경로명 객체의 구성요소를 채웁니다.

DESCRIBE 함수를 사용하면 경로 이름의 구성 요소를 볼 수 있습니다(여기서는 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
  • Lisp 함수를 사용하여 경로 이름 객체 만들기

MAKE-PATHNAME은 함수이며 구성 요소를 지정하기 위해 몇 가지 키워드 인수가 필요합니다.

때로는 기존 경로 이름을 기반으로 새 경로 이름을 만드는 것도 유용합니다.

(make-pathname :name "foo" :defaults (pathname "/Users/bar/baz.text"))

DIRECTORY를 사용하는 경우 와일드카드와 함께 경로 이름을 사용하는 것이 유용합니다. 그런 다음 DIRECTORY는 일치하는 경로 이름 목록을 반환합니다.DIRECTORY는 디렉토리의 내용을 나열하지 않고 일반적으로 경로 이름과 일치하는 경로 이름을 와일드카드와 함께 나열하므로 'DIRECTORY'라는 이름은 약간 오해의 소지가 있습니다.와일드카드는 /foo/s*c/list*.l*"와 같은 구성 요소의 문자 시퀀스와 일치할 수 있습니다./foo/**/test.lisp 와 같은 디렉토리 계층 구조의 일부를 일치시키는 데 사용되는 와일드카드 ** 도 있습니다. 이는 foo 디렉토리 및 그 하위 디렉토리 아래의 모든 test.lisp 파일과 일치합니다.

(directory "/Users/foo/Lisp/**/*.lisp")

위에서는 '/Users/foo/Lisp/' 및 모든 하위 디렉터리에 있는 모든 'lisp' 파일 목록을 반환해야 합니다.

단일 디렉터리에 .c 파일을 반환하려면 다음을 사용하세요.

(directory "/Users/foo/c/src/*.c")

DIRECTORY는 경로명 객체 목록을 반환합니다(문자열 목록이 아님).

? (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 경로 이름 구문에 따라 다릅니다.

현대식 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")

후행 슬래시 나 와일드 카드가 필요하지 않습니다. 매우 강력하고 인코딩 된 유니 코드 문자로 파일 이름을 처리 할 수도 있습니다.

CL-FAD와 비교 한 차이점 :

  • 당신이 얻는 객체는 iolib 파일 경로이며, CL의 경로 이름을 대체하여 기본 OS가하는 일이 더 가깝습니다.
  • IOLIB는 CFFI를 사용하여 루틴을 구현하므로 모든 LISP 구현에서 동일하게 작동하며 (IOLIB가 운영 체제에 대한 백엔드가있는 경우) CL-FAD와 달리 구현의 디렉토리 기능을 추상화하려고 시도합니다.
  • CL-FAD와 달리 IOLIB는 Symlinks (Windows IMHO 이외의 플랫폼에서는 거의 사용할 수없는 CL-FAD의 주요 문제 중 하나)를 올바르게 처리합니다.

코드 스 니펫을 위해 저에게 적합한 예를 추가하겠습니다. 나는 사용한다 오시 카 (CL-FAD와 유사) 및 스트리트.

편집하다: 또한 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")

와일드 카드의 적절한 사용을 확실히 개선 할 수 있습니다. 그러나 그것은 당신이 지금 사용할 수있는 스 니펫입니다 :)

참조 :

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top