Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

vl-directory-files for subdirectories

8 REPLIES 8
Reply
Message 1 of 9
DGRL
2927 Views, 8 Replies

vl-directory-files for subdirectories

Dear coders

 

In 1 of my routines I use vl-directory-files to get all *.dwg in a dir

Now I want to know if it is possible with minor tweaking if vl-directory-files can also read out the subdirectories.

 

 

If this was of any help please kudo and/or Accept as Solution
Kind Regards
8 REPLIES 8
Message 2 of 9
john.uhden
in reply to: DGRL

From my ACAD2002 help:

 

vl-directory-files [AutoLISP Reference: VLR]

(vl-directory-files [directory pattern directories])

Arguments

directory

A string naming the directory to collect files for; if nil or absent, vl-directory-files uses the current directory.

pattern

A string containing a DOS pattern for the file name; if nil or absent, vl-directory-files assumes "*.*"

directories

An integer that indicates whether the returned list should include directory names. Specify one of the following:

-1 List directories only.

0 List files and directories (the default).

1 List files only.

 

;;-------------------------------------------------------------------------------------
;; Function to build a list of drawings found in the specified path and subdirectories:
(defun @find_dwgs (path / spec files spaces dirs @dirs)
  (cond
    ((or (/= (type path) 'STR)(= path ""))
      (setq path
        (strcase
          (vl-filename-directory
            (findfile
              (car (vl-directory-files "" "*.*" 1))
            )
          )
        )
      )
    )
    ((wcmatch path ",*/,*\\"))
    (1 (setq path (strcat path "\\")))
  )
  (setq spec "*.dwg")
  (setq spaces "                                                                                               ")
  (defun @dirs (path / dirs found)
    (princ (strcat "\rSearching " path (substr spaces (strlen path))))
    (princ)
    (and
      (setq found (vl-directory-files path spec 1))
      (setq found (mapcar (function (lambda (x)(strcat path x))) found))
      (setq files (append files found))
    )
    (and
      (setq dirs (vl-directory-files path "*.*" -1))
      (setq dirs (vl-remove-if (function (lambda (x)(vl-position x '("." "..")))) dirs)
            dirs (mapcar (function (lambda (x)(strcat path x "\\"))) dirs)
      )
    )
    (foreach dir dirs (@dirs dir))
  )
  (terpri)
  (@dirs path)
  (reverse files)
)

 

John F. Uhden

Message 3 of 9
_gile
in reply to: DGRL

Hi,

 

You have to make a recursive search.

 

 

(defun allfiles	(folder pattern)
  (apply 'append
	 (cons (if (vl-directory-files folder pattern)
		 (mapcar '(lambda (x) (strcat folder "\\" x))
			 (vl-directory-files folder pattern)
		 )
	       )
	       (mapcar '(lambda (x) (allfiles (strcat folder "\\" x) pattern))
		       (vl-remove ".." (vl-remove "." (vl-directory-files folder nil -1)))
	       )
	 )
  )
)

 

Run:

 

(allfiles dir "*.dwg")

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 4 of 9
DannyNL
in reply to: DGRL

Here is my solution.

If you want to scan for files use FileScan, if you only want folders use FolderScan.

 

;;;
;;; FileScan
;;;
;;; Usage: (FileScan [Path] [Pattern] [SubFolderScan])
;;;
;;; [Path]          - Folder to scan
;;; [Pattern]       - File pattern to search for
;;; [SubFolderScan] - Include subfolders in filescan
;;;

(defun FileScan (FS_Path FS_Pattern FS_SubFolders / FS_FileList FS_FolderList FS_ScanList)
   (if
      (and
         (= (type FS_Path)    'STR)         
         (= (type FS_Pattern) 'STR)
         (/= (vl-filename-directory FS_Path) "")
      )
      (progn
         (setq FS_Path (strcat (vl-string-right-trim "\\/" FS_Path) "\\"))
         (if
            FS_SubFolders
            (setq FS_FolderList (FolderScan FS_Path T T))
            (setq FS_FolderList (list FS_Path))
         )
         (foreach FS_Folder FS_FolderList
            (setq FS_ScanList   (vl-directory-files FS_Folder FS_Pattern 1))
            (if
               FS_ScanList
               (setq FS_FileList (append FS_FileList (list (list FS_Folder FS_ScanList))))
            )
         )               
      )
   )
   FS_FileList
)


;;;
;;; FolderScan
;;;
;;; Usage: (FolderScan [Path] [SubFolderScan] [IncludeBase])
;;;
;;; [Path]          - Folder to scan
;;; [SubFolderScan] - Include subfolders
;;; [IncludeBase]   - Include [Path] in returnlist
;;;

(defun FolderScan (FS_BasePath FS_SubFolders FS_IncludeBase / FS_ScanList FS_FolderList FS_FullPath)
   (if
      (and
         (= (type FS_BasePath) 'STR)
         (/= (vl-filename-directory FS_BasePath) "")
      )
      (progn               
         (setq FS_BasePath (strcat (vl-string-right-trim "\\/" FS_BasePath) "\\"))               
         (setq FS_ScanList (vl-remove "." (vl-remove ".." (vl-directory-files FS_BasePath "*" -1))))
         (foreach FS_Folder FS_ScanList
            (if
               (not (member FS_Folder FS_FolderList))
               (setq FS_FolderList (append FS_FolderList (list (setq FS_FullPath (strcat FS_BasePath FS_Folder "\\")))))
            )
            (if
               FS_SubFolders
               (setq FS_FolderList (append FS_FolderList (FolderScan FS_FullPath T nil)))
            )
         )
         (if
            (and
               (not (member FS_BasePath FS_FolderList))
               FS_IncludeBase
            )
            (setq FS_FolderList (append (list FS_BasePath) FS_FolderList))
         )
      )
   )
   FS_FolderList
)
Message 5 of 9
aclarke
in reply to: _gile

Hi,

What is "." and ".." that is  being removed in your code and shown in the help result linked below?

 

Thanks

 

https://knowledge.autodesk.com/search-result...

Message 6 of 9
_gile
in reply to: aclarke

They're used for relative paths. "." stands for current directory and ".." for parent directory.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 7 of 9
dbroad
in reply to: _gile

Hi @_gile ,

Would your function operate any differently if written like this?

(DEFUN allfiles	(folder pattern)
  (APPLY
    'APPEND
    (CONS (MAPCAR '(LAMBDA (x) (STRCAT folder "\\" x))
		  (VL-DIRECTORY-FILES folder pattern)
		  )
	  (MAPCAR
	    '(LAMBDA (x) (allfiles (STRCAT folder "\\" x) pattern))
	    (VL-REMOVE ".."
		       (VL-REMOVE "." (VL-DIRECTORY-FILES folder nil -1))
		       )
	    )
	  )
    )
  )

I think the result will be the same and don't expect the timing to be much different.

Architect, Registered NC, VA, SC, & GA.
Message 8 of 9
_gile
in reply to: dbroad

No, both are quite similar, the main difference seems to be using uppercase or lowercase 😉



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 9 of 9
dbroad
in reply to: _gile

🙂 Just autoformatted that way. I just took out the if statement.

Architect, Registered NC, VA, SC, & GA.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost