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.
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
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")
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 )
Hi,
What is "." and ".." that is being removed in your code and shown in the help result linked below?
Thanks
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.