Author Topic: Search folder  (Read 3004 times)

0 Members and 1 Guest are viewing this topic.

MeasureUp

  • Bull Frog
  • Posts: 465
Search folder
« on: February 06, 2013, 06:34:24 PM »
There may be a "Fasteners" sub-folder in "Library" under "C" directory.
The sub-folder name may also be "Fasteners (non-STD)"...
My questions are:
1) How to find if a sub-folder name contains "Fasteners"? And if it is exist (if not, create the sub-folder "Fasteners"), then
2) Get the path.

Thanks in advance.
« Last Edit: February 06, 2013, 06:48:36 PM by MeasureUp »

Lee Mac

  • Seagull
  • Posts: 12928
  • London, England
Re: Search folder
« Reply #1 on: February 06, 2013, 07:01:21 PM »
Perhaps something along the lines of:
[ Note! This recursively searches every subfolder of every subfolder ... of every subfolder under the given root ]
Code: [Select]
(defun _searchforfolder ( root pattern / folder folders )
    (if
        (setq folder
            (vl-some
                (function
                    (lambda ( folder )
                        (if (wcmatch (strcase folder) (strcase pattern))
                            folder
                        )
                    )
                )
                (setq folders
                    (vl-remove-if '(lambda ( x ) (wcmatch x "`.,`.`."))
                        (vl-directory-files
                            (setq root
                                (vl-string-right-trim "\\" (vl-string-translate "/" "\\" root))
                            )
                            nil -1
                        )
                    )
                )
            )
        )
        (strcat root "\\" folder)
        (vl-some
            (function
                (lambda ( folder )
                    (_searchforfolder (strcat root "\\" folder) pattern)
                )
            )
            folders
        )
    )
)
Code: [Select]
(_searchforfolder "C:\\Library" "*Fasteners*")


To search only the root directory for a matching folder:
Code: [Select]
(defun _searchforfolder ( root pattern / folder )
    (if
        (setq folder
            (vl-some
                (function
                    (lambda ( folder )
                        (if (wcmatch (strcase folder) (strcase pattern))
                            folder
                        )
                    )
                )
                (vl-remove-if '(lambda ( x ) (wcmatch x "`.,`.`."))
                    (vl-directory-files
                        (setq root
                            (vl-string-right-trim "\\" (vl-string-translate "/" "\\" root))
                        )
                        nil -1
                    )
                )
            )
        )
        (strcat root "\\" folder)
    )
)
Code: [Select]
(_searchforfolder "C:\\Library" "*Fasteners*")
Or, you can use the 'pattern' parameter of the vl-directory-files function:
Code: [Select]
(defun _searchforfolder ( root pattern )
    (vl-directory-files (vl-string-right-trim "\\" (vl-string-translate "/" "\\" root)) pattern -1)
)
Code: [Select]
(_searchforfolder "C:\\Library" "*Fasteners*")

To create the folder, use the vl-mkdir function


Of course, all of these functions could equally be derived from the FileSystemObject.
« Last Edit: February 06, 2013, 07:10:12 PM by Lee Mac »

MeasureUp

  • Bull Frog
  • Posts: 465
Re: Search folder
« Reply #2 on: February 06, 2013, 10:28:22 PM »
Thanks Lee for your explanation.
But one thing I don't know is how to get the path which contains the folder with *Fasteners* name?

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1454
  • Marco
Re: Search folder
« Reply #3 on: February 07, 2013, 04:01:54 AM »
Another example with my old functions:
Code: [Select]
; Marc'Antonio Alessi, Italy - http://xoomer.virgilio.it/alessi
;
; Function: ALE_UtlFilesGetFolders
;
; Version 1.00 - 09/06/2006
;
; Description:
;   Returns a list of subdirectories found in the specified directory,
;   the return values contain trailing double-backslashes (\\)
;   if RecFlg = T > scan the entire structure
;
; Arguments:
;   In_Pat = A string containing an existing path
;            do not need trailing double-backslashes
;            if nil or "" uses the current directory.

;   RecFlg = flag > 1 = scan the entire structure
;                 > 0 = do not scan
;
; Examples:
;   (ALE_UtlFilesGetFolders "C:\\Temp" nil)
;   (ALE_UtlFilesGetFolders "C:\\Temp\\" T)
;
; Return Values:
;   [LIST] A list of subdirectories if successful.
;
(defun ALE_UtlFilesGetFolders (In_Pat RecFlg / FilNam OutLst)
  (or
    (wcmatch In_Pat "*[\\/]")
    (setq In_Pat (strcat In_Pat "\\"))
  )
  (if RecFlg
    (ALE_UtlFilesGetFolders_Aux In_Pat)
    (foreach ForElm (cddr (vl-directory-files In_Pat nil -1))
      (setq OutLst (cons (strcat In_Pat ForElm "\\") OutLst))
    )
  )
  (reverse OutLst)
)
;
; Function: ALE_UtlFilesGetFolders_Aux
; Auxiliary function for: ALE_UtlFilesGetFolders
;
(defun ALE_UtlFilesGetFolders_Aux (In_Pat)
  (foreach ForElm (cddr (vl-directory-files In_Pat nil -1))
    (setq
      FilNam (strcat In_Pat ForElm "\\")
      OutLst (cons FilNam OutLst)
    )
    (ALE_UtlFilesGetFolders_Aux FilNam)
  )
)

(defun mkdir_fastener ( / TrueFl)
  (foreach ForElm (ALE_UtlFilesGetFolders "C:\\Library" nil)
    (and (wcmatch ForElm "*Fasteners*") (setq TrueFl T))
  )
  (or TrueFl (vl-mkdir "C:\\Library\\Fasteners"))
)

Lee Mac

  • Seagull
  • Posts: 12928
  • London, England
Re: Search folder
« Reply #4 on: February 07, 2013, 07:14:24 AM »
But one thing I don't know is how to get the path which contains the folder with *Fasteners* name?

Did you try my posted examples?


MeasureUp

  • Bull Frog
  • Posts: 465
Re: Search folder
« Reply #5 on: February 07, 2013, 08:25:30 PM »
Thanks Lee.
It works!
I have done couple of test.
I found that the search runs 5sec to finish when the target is in the server while it finishes immediately when searching in local drive.
What was wrong?

Edit: Problem solved. The selected path in the server for the test has too many levels and it makes the code too busy. Thanks again.
« Last Edit: February 07, 2013, 11:00:41 PM by MeasureUp »

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1454
  • Marco
Re: Search folder
« Reply #6 on: February 08, 2013, 02:04:56 AM »
...
Edit: Problem solved. The selected path in the server for the test has too many levels and it makes the code too busy. Thanks again.
my version is slow?

Lee Mac

  • Seagull
  • Posts: 12928
  • London, England
Re: Search folder
« Reply #7 on: February 08, 2013, 06:48:25 AM »
Thanks Lee.
It works!

Good stuff, you're welcome  :-)

MeasureUp

  • Bull Frog
  • Posts: 465
Re: Search folder
« Reply #8 on: February 12, 2013, 04:47:37 PM »
...
Edit: Problem solved. The selected path in the server for the test has too many levels and it makes the code too busy. Thanks again.
my version is slow?
Thanks Marc'Antonio Alessi.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Search folder
« Reply #9 on: February 13, 2013, 12:39:21 AM »
We've run into a similar thing in the past: i.e. long and large lists of nested folders tend to take ages to search through (even if on a local disc). The fastest way would be to limit the number of recursions (if possible): http://forums.augi.com/showthread.php?132773-Search-file-in-a-specific-drive&p=1141241&viewfull=1#post1141241

Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

MeasureUp

  • Bull Frog
  • Posts: 465
Re: Search folder
« Reply #10 on: February 13, 2013, 06:47:58 PM »
Thanks irneb.