How to search for wildcard files in Common Lisp?

I am not happy with finding files matching the string:

(remove-if-not (lambda (it)
                   (search "wildcard" (namestring it)))
               (uiop:directory-files "./"))
;; I'll ignore case with str:contains?
;; https://github.com/vindarel/cl-str

How to search for unix style wildcard files?

If it is not built in, I would like a solution with uiop . Perhaps there is Osicat or cl-fad (which it doesn't look like with, the documentation often says "non-differential path name").

Bonus if you can use a double template to recursively move directories ( ./**/*.jpg).

edit . I have tried variations (directory #p"./**/*.jpg")and returns nil :( also tried #p".*jpg", #p"./.*jpg"...

(wild-pathname-p (pathname "*.jpg"))
(:WILD :WILD-INFERIORS)


(make-pathname :name :wild :type "jpg")
#P"*.jpg"

The following are files with the jpg extension, but this is not a valid template:

(directory *)
(#P"/home/vince/cl-cookbook/AppendixA.jpg"
 #P"/home/vince/cl-cookbook/AppendixB.jpg"
 #P"/home/vince/cl-cookbook/AppendixC.jpg")

make-pathname: http://gigamonkeys.com/book/files-and-file-io.html ( )

+4
2

SBCL

SBCL . :

(loop 
  with stem = #P"/tmp/stack/_.txt"
  initially (ensure-directories-exist stem)
  for name in '("abc" "def" "cadar" "cdadr" "cddr")
  for path = (make-pathname :name name :defaults stem)
  do (open path :direction :probe :if-does-not-exist :create))

, "a":

CL-USER> (directory #P"/tmp/stack/*a*.txt")
(#P"/tmp/stack/abc.txt" #P"/tmp/stack/cadar.txt" #P"/tmp/stack/cdadr.txt")

, ():

CL-USER> (describe #P"/tmp/stack/*a*.txt")
#P"/tmp/stack/*a*.txt"
  [structure-object]

Slots with :INSTANCE allocation:
  HOST       = #<SB-IMPL::UNIX-HOST {10000F3FF3}>
  DEVICE     = NIL
  DIRECTORY  = (:ABSOLUTE "tmp" "stack")
  NAME       = #<SB-IMPL::PATTERN :MULTI-CHAR-WILD "a" :MULTI-CHAR-WILD>
  TYPE       = "txt"
  VERSION    = :NEWEST
; No value

SBCL sb-ext:map-directory, , .

, directory :

CL-USER> (remove-if-not (wildcard "*a*")
                        (directory #P"/tmp/stack/*.txt")
                        :key #'pathname-name)

(#P"/tmp/stack/abc.txt" #P"/tmp/stack/cadar.txt" #P"/tmp/stack/cdadr.txt")

... wildcard regex (PPCRE):

(defun parse-wildcard (string)
  (delete ""
          (map 'list
               (lambda (string)
                 (or (cdr (assoc string
                                 '(("*" . :wild)
                                   ("?" . :char))
                                 :test #'string=))
                     string))
               (ppcre:split '(:sequence
                              (:negative-lookbehind #\\)
                              (:register (:alternation #\* #\?)))
                            string
                            :with-registers-p t))
          :test #'string=))

(: lookbehind escape- )

(defun wildcard-regex (wildcard)
  `(:sequence
    :start-anchor
    ,@(loop
        for token in wildcard
        collect (case token
                  (:char :everything)
                  (:wild '(:greedy-repetition 0 nil :everything))
                  (t token)))
    :end-anchor))

(defun wildcard (string)
  (let ((scanner (ppcre:create-scanner
                  (wildcard-regex (parse-wildcard string)))))
    (lambda (string)
      (ppcre:scan scanner string))))

:

CL-USER> (parse-wildcard "*a*a\\*a?\\?a")
(:WILD "a" :WILD "a\\*a" :CHAR "\\?a")

CL-USER> (wildcard-regex (parse-wildcard "*a*a\\*a?\\?a"))
(:SEQUENCE :START-ANCHOR #1=(:GREEDY-REPETITION 0 NIL :EVERYTHING) "a" #1# "a\\*a" :EVERYTHING "\\?a" :END-ANCHOR)
+7

., , Common Lisp. .

~ . .

pathname * ** . .

Lisp *default-pathname-defaults*, .

< >

CL-USER 46 > (directory "/bin/*")
(#P"/bin/[" #P"/bin/bash" #P"/bin/cat"   ....   )

undefined , Unix:

  • ?
  • '' ?
  • ?

:

CL-USER 47 > (directory "/bin/*sh")
(#P"/bin/zsh" #P"/bin/tcsh" #P"/bin/sh" #P"/bin/ksh" #P"/bin/csh" #P"/bin/bash")

:

CL-USER 48 > (let ((*default-pathname-defaults* (pathname "/bin/")))
               (directory "*sh"))
(#P"/bin/zsh" #P"/bin/tcsh" #P"/bin/sh" #P"/bin/ksh" #P"/bin/csh" #P"/bin/bash")

:

CL-USER 49 > (let ((*default-pathname-defaults* (user-homedir-pathname)))
              (directory "*"))

:

CL-USER 54 > (directory (make-pathname :name "*"
                                       :defaults (user-homedir-pathname)))

, sh /usr/local/ :

CL-USER 54 > (directory "/usr/local/**/*sh")

MAKE-PATHNAME

.h /usr/local/:

(directory "/usr/local/**/*.h")

(directory (make-pathname :name :wild
                          :type "h"
                          :defaults "/usr/local/**/")

(directory
   (make-pathname :name :wild
                  :type "h"
                  :directory '(:ABSOLUTE "usr" "local" :WILD-INFERIORS)))

( "windows", "unix", "mac",...) ( "windows" "unix" ). , unicode pathnames, - CL.

(https://en.wikipedia.org/wiki/List_of_file_systems), , , Lisp. , .

+3

Source: https://habr.com/ru/post/1693749/


All Articles