File search for all files of same name.

Discussion in 'AutoCAD' started by BillZ, May 21, 2004.

  1. BillZ

    BillZ Guest

    R2005 Vlisp:

    Is there a way to search all directories for any files of the same name without using a third party app?

    I can do it with dos_find but I do not like this way because once you execute the search you lose control over using any progress bars or escapes. I would like more of a loop type.

    TIA

    Bill
     
    BillZ, May 21, 2004
    #1
  2. BillZ

    ECCAD Guest

    You can do it with VB, don't know about recursion in VLisp.
    If you want, I can provide VB source for a small .exe you could fire up.

    Bob
     
    ECCAD, May 21, 2004
    #2
  3. It's not so much the loop that you require but an implementation
    that utilizes a DoEvents statement in said loop (if I understand
    your post).

    R2005 Vlisp:

    Is there a way to search all directories for any files of the same name without using a third party app?

    I can do it with dos_find but I do not like this way because once you execute the search you lose control over using any progress
    bars or escapes. I would like more of a loop type.

    TIA

    Bill
     
    michael puckett, May 21, 2004
    #3
  4. BillZ

    BillZ Guest

    Yes, I think you're right.

    But can you do a "DoEvents" with Vlisp?

    I don't know any VB at this time.

    Bill
     
    BillZ, May 21, 2004
    #4
  5. Not too my knowledge.

    Before I go off on a tangent of possible work-arounds can
    you supply a little more information? I mean you say "lose
    control over using any progress bars or escapes", but it
    sounds like you want a vlisp solution. Are you doing dialogs
    in DCL / ObjectDCL? If so you could write your own vlisp based
    search engine using vl-directory-files that updates specific
    tiles on every nth iteration. Something like that. But again,
    I really don't know what you're after. Perhaps psychic Rudy
    can chime in :)

    Yes, I think you're right.

    But can you do a "DoEvents" with Vlisp?

    I don't know any VB at this time.

    Bill
     
    michael puckett, May 21, 2004
    #5
  6. You could also write a recursive search engine as an activex
    dll (incorporating a DoEvents) and then instantiate / call from
    vlisp. Mind you, either way, DoEvents or "tile refreshing" you
    will realize a performance hit.

    Not too my knowledge.

    Before I go off on a tangent of possible work-arounds can
    you supply a little more information? I mean you say "lose
    control over using any progress bars or escapes", but it
    sounds like you want a vlisp solution. Are you doing dialogs
    in DCL / ObjectDCL? If so you could write your own vlisp based
    search engine using vl-directory-files that updates specific
    tiles on every nth iteration. Something like that. But again,
    I really don't know what you're after. Perhaps psychic Rudy
    can chime in :)

    Yes, I think you're right.

    But can you do a "DoEvents" with Vlisp?

    I don't know any VB at this time.

    Bill
     
    michael puckett, May 21, 2004
    #6
  7. BillZ

    BillZ Guest

    Thanks MP,
    At least I'm seeing what my limitations are in this situation.

    I am using <ugh> regular DCL.

    You cannot escape from or stop a (dos_find, believe me.

    I do not know what a " recursive search engine " is but what I think I need to do now is to get a list of all the directories under "G:" drive. Then I can do a findfile for each item in the list, with a fill_image every 100 counts or so.
    I do this already on another type of search that is a bit smaller and has an available list to search.
    My problem right now is getting a list of all the directories under G: drive using vl-directory-files.

    This is what I have so far:
    (defun AllDirList ()
    (vl-load-com)
    (setq dir_main (vl-remove-if '(lambda (str)
    (member (strcase str) '("." "..")))
    (vl-directory-files "G:/" nil -1))
    dir_lst (mapcar '(lambda (x)(strcat "G:\\" x "\\")) dir_main)
    )
    (setq next_round (mapcar '(lambda (x)
    (vl-remove-if '(lambda (str)(member (strcase str)'("." "..")))
    (vl-directory-files x nil -1))) dir_lst))
    (princ)
    )

    Can I loop this whole mess into one while or mapcar so it continues until there are no more directories?

    Thanks

    Bill
     
    BillZ, May 21, 2004
    #7
  8. I had written a recursive (vlisp) search a number of
    years ago, but (modesty aside) I believe I could write
    a far better one now, so I'd like to follow that challenge.
    However, I don't have time right at this moment. If no
    one else posts one I'll code one up tonite or tomorrow
    and (try to) put a hook into it so it could call another
    function (eg. refresh a progress tile) every nth
    iteration. You could use that approach so the user gets
    some indication the application has not died.

    Also, for fun I may code up a dll to show you how it
    might be done going that route (return an array of strings
    to the caller), though once control is transferred to a
    dll I do not believe a DoEvents will enable event
    processing back at a previously displayed dcl dialog,
    unless ... hmmm, pass the application object to the dll ...
    let me think / experiment on that.

    Anyway, it really depends on how much time I'll have
    available this weekend (will be busy coding a different
    project), but I'll certainly see what I can do.

    Cheers.

    Thanks MP,
    At least I'm seeing what my limitations are in this situation.

    I am using <ugh> regular DCL.

    You cannot escape from or stop a (dos_find, believe me.

    I do not know what a " recursive search engine " is but what I think I need to do now is to get a list of all the directories under
    "G:" drive. Then I can do a findfile for each item in the list, with a fill_image every 100 counts or so.
    I do this already on another type of search that is a bit smaller and has an available list to search.
    My problem right now is getting a list of all the directories under G: drive using vl-directory-files.

    This is what I have so far:
    (defun AllDirList ()
    (vl-load-com)
    (setq dir_main (vl-remove-if '(lambda (str)
    (member (strcase str) '("." "..")))
    (vl-directory-files "G:/" nil -1))
    dir_lst (mapcar '(lambda (x)(strcat "G:\\" x "\\")) dir_main)
    )
    (setq next_round (mapcar '(lambda (x)
    (vl-remove-if '(lambda (str)(member (strcase str)'("." "..")))
    (vl-directory-files x nil -1))) dir_lst))
    (princ)
    )

    Can I loop this whole mess into one while or mapcar so it continues until there are no more directories?

    Thanks

    Bill
     
    michael puckett, May 21, 2004
    #8
  9. BillZ

    Devin Guest

    Hi Bill,

    Here's an old routine I wrote that searches a directory and all
    sub-directorys and creates a script to be done on all drawings it finds.
    You could modify it to suite your needs. hth...

    (princ "\nC:OFILE - Create script file for Openning!")
    (princ "\nC:SFILE - Create script file for purging!")

    (defun C:OFILE ( / ed_file ed_path ed_wrk)
    (ed_init)
    (setq ed_cnt 0)
    (ggetstring "ed_infile" "Enter start directory to purge")
    (ed_extract_dwgs ed_infile)
    (if
    (setq ed_path (getfiled "Script Creator" "open.scr" "scr" 1))
    (setq ed_file (open ed_path "W"))
    (ed_exit "No file specified")
    )
    (foreach ed_wrk ed_lst
    (write-line ".OPEN" ed_file)
    (write-line (strcat "\"" ed_wrk "\"") ed_file)
    ;; (write-line (strcat "(princ \"\n" ed_wrk "\")" ed_file)
    (write-line ".CLOSE" ed_file)
    )
    (close ed_file)
    (princ (strcat "\nFound (" (itoa ed_cnt) ") dwg files!"))
    (princ "\nCreated file: ")(princ ed_path)
    (ed_deinit)
    )

    (defun C:SFILE ( / ed_file ed_path ed_wrk)
    (ed_init)
    (setq ed_cnt 0)
    (ggetstring "ed_infile" "Enter start directory to purge")
    (ed_extract_dwgs ed_infile)
    (if
    (setq ed_path (getfiled "Script Creator" "purge.scr" "scr" 1))
    (setq ed_file (open ed_path "W"))
    (ed_exit "No file specified")
    )
    (foreach ed_wrk ed_lst
    (write-line ".OPEN" ed_file)
    (write-line (strcat "\"" ed_wrk "\"") ed_file)
    (write-line "ZOOM" ed_file)
    (write-line "E" ed_file)
    (write-line "(repeat 5 (C:pGA))" ed_file)
    (write-line ".QSAVE" ed_file)
    (write-line ".CLOSE" ed_file)
    )
    (close ed_file)
    (princ (strcat "\nFound (" (itoa ed_cnt) ") dwg files!"))
    (princ "\nCreated file: ")(princ ed_path)
    (ed_deinit)
    )

    (defun ed_extract_dwgs ( ed_arg / ed_pass ed_wrk)

    (setq ed_pass (ed_strip_fl ed_arg))

    (foreach ed_wrk ed_pass
    (cond
    (
    (vl-filename-extension ed_wrk)
    (if
    (not (member ed_wrk ed_lst))
    (progn
    (princ "\nFound dwg: ")(princ ed_wrk)
    (setq ed_lst (cons ed_wrk ed_lst))
    (setq ed_cnt (1+ ed_cnt))
    )
    )
    )
    (
    (vl-file-directory-p ed_wrk)
    (ed_extract_dwgs ed_wrk)
    )
    )
    )
    (setq ed_pass ed_pass)
    )

    (defun ed_strip_fl ( ed_arg / ed_pass ed_wrk ed_tmp ed_path)
    (setq ed_pass (vl-directory-files ed_arg))
    (setq ed_path (strcat ed_arg "\\"))
    (if (member "." ed_pass) (setq ed_pass (vl-remove "." ed_pass)))
    (if (member ".." ed_pass) (setq ed_pass (vl-remove ".." ed_pass)))
    (foreach ed_wrk ed_pass
    (if
    (setq ed_tmp (vl-filename-extension ed_wrk))

    (if
    (equal ".DWG" (strcase ed_tmp))
    (setq ed_pass (subst (strcat ed_path ed_wrk) ed_wrk ed_pass))
    (setq ed_pass (vl-remove ed_wrk ed_pass))
    )

    (setq ed_pass (subst (strcat ed_path ed_wrk) ed_wrk ed_pass))
    )
    )
    (setq ed_pass ed_pass)
    )

    Devin
     
    Devin, May 21, 2004
    #9
  10. Visit www.caddzone.com and download the file vl-dbx.zip from the
    free stuff section.

    In it, you'll find several LISP functions that can process files
    and folders recursively. You can easily adapt them to search for
    specific files.

    The main entry point is the (map-file) function.

    This code will use it to find all instances of the
    file "findme.txt" on drive C:, and return a list
    containing their full paths:

    (defun map-file-example ( / found)
    (map-file "c:\\" "findme.txt" T
    '(lambda (path file)
    (setq found (cons (strcat path file) found))
    )
    )
    found
    )





    any progress bars or escapes. I would like more of a loop type.
     
    Tony Tanzillo, May 21, 2004
    #10
  11. BillZ

    ECCAD Guest

    Bill,
    Here is raw VB code to recurse dir's and find .dwgs.
    In case you were curious.

    ' Recursively search directories from strPath down...
    ' strPath is searched on this recursion.
    ' lngDirCount is number of subdirectories in this directory.
    Private Function blnSearchDirectories(ByVal strPath As String) As Boolean
    Dim strFileName As String
    Dim lngDirCount As Long, lngDirPointer As Long
    ReDim strDirectories(0) As String

    blnSearchFlag = True ' Set flag so the user can interrupt.
    blnSearchDirectories = False ' Set to True if there is an error.
    DoEvents ' Check for events (for instance, if the user chooses Cancel).
    If blnSearchFlag = False Then
    blnSearchDirectories = True
    Exit Function
    End If

    If Right$(strPath, 1) <> "\" Then strPath = strPath + "\"
    lblStatus.Caption = "Searching: " & strPath

    lngDirCount = 0
    strFileName = Dir(strPath & "*.*", vbDirectory)
    Do While strFileName <> ""
    If strFileName <> "." And strFileName <> ".." Then
    If (GetAttr(strPath & strFileName) And vbDirectory) = vbDirectory Then
    strDirectories(lngDirCount) = strPath & strFileName
    lngDirCount = lngDirCount + 1
    ReDim Preserve strDirectories(lngDirCount)
    Else
    If UCase$(Right$(strFileName, 4)) = ".DWG" Then
    strFileName = strPath + strFileName
    lstFoundFiles.AddItem strFileName
    lblCount.Caption = Str(Val(lblCount.Caption) + 1)
    End If
    End If
    End If
    strFileName = Dir()
    Loop
    If lngDirCount > 0 Then
    For lngDirPointer = 0 To lngDirCount - 1
    If blnSearchDirectories(strDirectories(lngDirPointer)) Then
    blnSearchDirectories = True
    Exit Function
    End If
    Next lngDirPointer
    End If

    End Function
     
    ECCAD, May 21, 2004
    #11
  12. BillZ

    devitg Guest

    Hi Devin , please check it for missing DEFUN , the first reported not to be is
    ed_init

    maybe , same as I do , you keep it on a other file .

    This king of routine will be usefull for me

    Thank in advance
     
    devitg, May 24, 2004
    #12
  13. BillZ

    BillZ Guest

    Michael,
    Thanks,
    I did write a file directory subr to get all directory/sub directory names under a drive into a list. (Thanks to the education you gave me on mapcar and lambda).
    With 1991 directories under my main drive it takes 1-1/2 minutes to run. I may set it to limit the directories for my app.

    (defun AllDirList (drive / dir_lst dir_main dir_nxt)
    (vl-load-com)
    (setq dir_lst (list drive))
    (while dir_lst
    (setq dir_nxt (mapcar '(lambda (x)
    (vl-remove-if '(lambda (str)(member (strcase str)'("." "..")))
    (vl-directory-files x nil -1))) dir_lst)
    dir_lst (mapcar '(lambda (a b) (mapcar '(lambda (x)(strcat a x "\\")) b )) dir_lst dir_nxt)
    dir_lst (apply 'append dir_lst)
    dir_main (append dir_lst dir_main)
    )
    ) ;end while
    (acad_strlsort dir_main)
    )

    Anyone using this might want to test this on thier systems as i have done limited testing on it. Modify as you wish.

    Bill
     
    BillZ, May 24, 2004
    #13
  14. BillZ

    BillZ Guest

    Thanks Devin,
    I'll have to check it out when I get time.

    Bill
     
    BillZ, May 24, 2004
    #14
  15. You're very welcome; glad you are on your way.

    Didn't Tony post to this thread? (From my home PC) I'm
    sure I saw him post a link or ref to some related functions
    on his web site. I don't see it here on my work PC. I was
    going to say "Make sure you check Tony's post". Maybe he
    pulled it (though I though we couldn't do that since the
    desk "improved" these forums).

    = Confused =

    Michael,
    Thanks,
    I did write a file directory subr to get all directory/sub directory names under a drive into a list. (Thanks to the education you
    gave me on mapcar and lambda).
    With 1991 directories under my main drive it takes 1-1/2 minutes to run. I may set it to limit the directories for my app.

    (defun AllDirList (drive / dir_lst dir_main dir_nxt)
    (vl-load-com)
    (setq dir_lst (list drive))
    (while dir_lst
    (setq dir_nxt (mapcar '(lambda (x)
    (vl-remove-if '(lambda (str)(member (strcase str)'("." "..")))
    (vl-directory-files x nil -1))) dir_lst)
    dir_lst (mapcar '(lambda (a b) (mapcar '(lambda (x)(strcat a x "\\")) b )) dir_lst dir_nxt)
    dir_lst (apply 'append dir_lst)
    dir_main (append dir_lst dir_main)
    )
    ) ;end while
    (acad_strlsort dir_main)
    )

    Anyone using this might want to test this on thier systems as i have done limited testing on it. Modify as you wish.

    Bill
     
    michael puckett, May 25, 2004
    #15
  16. BillZ

    ECCAD Guest

    Michael,
    Tony T posted, near bottom on Web Side.

    Bob
     
    ECCAD, May 25, 2004
    #16
  17. BillZ

    BillZ Guest

    Thanks Tony,

    I will be looking into that as time permits.

    I got the download.

    Bill
     
    BillZ, May 25, 2004
    #17
  18. Still don't see it :(

    Michael,
    Tony T posted, near bottom on Web Side.

    Bob
     
    michael puckett, May 25, 2004
    #18
  19. BillZ

    BillZ Guest

    Michael,
    Tony did post, and I got the .zip.

    For now, my new function is as fast as dos_find and I can cancel out if desired. I haven't found a good way to indicate progress yet, so I added a "Yes/No" dialog for the user that warns of a 2-4 minute wait although it rarely takes more than 2 minutes. I'll look at TT's as time permits.

    Thanks again.

    Bill

    <<<<<<<<<<<<<<

    (load "g:/autolisp/autolisp/subr/DirListSearch")
    (set_tile "alrt1" "Finding Directories:")
    (setq dir_srch (DirListSearch "g:\\"))
    (set_tile "alrt1" "Searching Directories:")
    (setq srch_ret (mapcar '(lambda (x)(vl-directory-files x (strcat "*" rst "*.dwg"))) dir_srch))
    (set_tile "alrt1" "Compiling File List:")
    (setq srch (mapcar '(lambda (a b) (mapcar '(lambda (x)(strcat a x)) b )) dir_srch srch_ret)
    srch (apply 'append srch)
    )
    ;;Go to display list function.
     
    BillZ, May 25, 2004
    #19
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.