Sign in to follow this  
Followers 0
blackey

Search folders recursively

12 posts in this topic

#1 ·  Posted (edited)

I have a folder that contains all of my music in seperate folders and i am trying to make a script that when a user enteres all or part of a artist it will search the parent folder recursively to search all folders and return any results it may find from my query.

Im sure this has to be done before, i just can't figure it out.

Any ideas how to search folders recursively?

Edited by blackey

Share this post


Link to post
Share on other sites



This script recuses a directory or drive and generates a logfile, I'm sure you can modify it to your needs

$logfile = FileOpen ("C:\DirectoryList.txt",2)
Search ("c:");replace with your search directory

Func Search($current)

    Local $search = FileFindFirstFile($current & "\*.*")
    While 1
        Dim $file = FileFindNextFile($search)
        If @error Or StringLen($file) < 1 Then ExitLoop
        If Not StringInStr(FileGetAttrib($current & "\" & $file), "D") And ($file <> "." Or $file <> "..") Then
        
        If $current & "\" & $file <> "C:\DirectoryList.txt"  then FileWriteLine ($logfile,$current & "\" & $file)
            
        EndIf
        If StringInStr(FileGetAttrib($current & "\" & $file), "D") And ($file <> "." Or $file <> "..") Then
            Search($current & "\" & $file)
            
        EndIf
    WEnd
    FileClose($search)

EndFunc

Func OnAutoitExit()
    FileClose ($logfile)
EndFunc

Share this post


Link to post
Share on other sites

This might be of more use, based on the above

Search ("c:", "Artist");replace with your search directory and Part of file name

Func Search($current,$searchQuery)

    Local $search = FileFindFirstFile($current & "\*.*")
    While 1
        Dim $file = FileFindNextFile($search)
        If @error Or StringLen($file) < 1 Then ExitLoop
        If Not StringInStr(FileGetAttrib($current & "\" & $file), "D") And ($file <> "." Or $file <> "..") Then

            If StringInStr($current & "\" & $file, $searchQuery) then 
                MsgBox (0, "Has the searchQuery " & $searchQuery, $current & "\" & $file)
                ;this is where you do what you need to do
            Endif
        EndIf
        If StringInStr(FileGetAttrib($current & "\" & $file), "D") And ($file <> "." Or $file <> "..") Then
            Search($current & "\" & $file, $searchQuery)
            
        EndIf
    WEnd
    FileClose($search)

EndFunc

Share this post


Link to post
Share on other sites

I tried copying the script that was entered above and i received the following error...

>"C:\Program Files\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "C:\Documents and Settings\blackey02\Desktop\New AutoIt v3 Script.au3" /autoit3dir "C:\Program Files\AutoIt3" /UserParams

>Running AU3Check params: from:C:\Program Files\AutoIt3\SciTE\au3check\

+>AU3Check ended.rc:0

>Running:(3.1.1.0):C:\Program Files\AutoIt3\autoit3.exe "C:\Documents and Settings\blackey02\Desktop\New AutoIt v3 Script.au3"

C:\Documents and Settings\blackey02\Desktop\New AutoIt v3 Script.au3 (5) : ==> Unable to open file, the maximum number of open files has been exceeded.:

Local $search = FileFindFirstFile($current & "\*.*")

C:\Documents and Settings\blackey02\Desktop\New AutoIt v3 Script.au3 (5) : ==> Error in expression.:

Local $search = FileFindFirstFile($current & "\*.*")

Local $search = ^ ERROR

+>AutoIT3.exe ended.rc:0

>Exit code: 0 Time: 0.539

Share this post


Link to post
Share on other sites

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

This means you have too many subdirectory levels.

This version doesn't have that issue:

; AutoIt Version: 3.0
; Language:       English
; Platform:       Win9x/NT/XP
; Author:         jos van der Zande
;
; Find files in directory and subdirectories and return it in an Array, all coded in Autoit3
; 
Dim $FILES
Dim $DIR="c:\winutil\autoit3\programs\test"  ; specify the directory to search
Dim $FILEMASK="*.au3"                        ; specify the filemask

$FILES = _GetFileList($DIR, $FILEMASK)
For $X = 0 To UBound($FILES)-1
   MsgBox(0,'test:' & $X,$FILES[$X])
Next 
Exit
;********************************************************************************
;Recursive search for filemask
;********************************************************************************

Func _GetFileList($T_DIR,$T_MASK)
   Dim $N_DIRNAMES[200000] ; max number of directories that can be scanned
   Local $N_DIRCOUNT = 0
   Local $N_FILE
   Local $N_SEARCH
   Local $N_TFILE
   Local $N_OFILE
   Local $T_FILENAMES
   Local $T_FILECOUNT
   Local $T_DIRCOUNT = 1
   ; remove the end \ If specified
   If StringRight($T_DIR,1) = "\" Then $T_DIR = StringTrimRight($T_DIR,1)
   $N_DIRNAMES[$T_DIRCOUNT] = $T_DIR
   ; Exit if base dir doesn't exists
   If Not FileExists($T_DIR) Then Return 0
   ; keep on looping until all directories are scanned
   While $T_DIRCOUNT > $N_DIRCOUNT
      $N_DIRCOUNT = $N_DIRCOUNT + 1
      ; find all subdirs in this directory and save them in a array
      $N_SEARCH = FileFindFirstFile($N_DIRNAMES[$N_DIRCOUNT] & "\*.*")  
      While 1
         $N_FILE = FileFindNextFile($N_SEARCH) 
         If @error Then ExitLoop
         ; skip these references
         If $N_FILE = "." Or $N_FILE = ".." Then ContinueLoop
         $N_TFILE = $N_DIRNAMES[$N_DIRCOUNT] & "\" & $N_FILE
         ; if Directory than add to the list of directories to be processed 
         If StringInStr(FileGetAttrib( $N_TFILE ),"D") > 0 Then
            $T_DIRCOUNT = $T_DIRCOUNT + 1
            $N_DIRNAMES[$T_DIRCOUNT] = $N_TFILE
         EndIf
      Wend
      FileClose($N_SEARCH)
      ; find all Files that mtach the MASK
      $N_SEARCH = FileFindFirstFile($N_DIRNAMES[$N_DIRCOUNT] & "\" & $T_MASK )  
      If $N_SEARCH = -1 Then ContinueLoop
      While 1
         $N_FILE = FileFindNextFile($N_SEARCH) 
         If @error Then ExitLoop
         ; skip these references
         If $N_FILE = "." Or $N_FILE = ".." Then ContinueLoop
         $N_TFILE = $N_DIRNAMES[$N_DIRCOUNT] & "\" & $N_FILE
         ; if Directory than add to the list of directories to be processed 
         If StringInStr(FileGetAttrib( $N_TFILE ),"D") = 0 Then
            $T_FILENAMES  = $T_FILENAMES & $N_TFILE & @CR
            $T_FILECOUNT = $T_FILECOUNT + 1
            ;MsgBox(0,'filecount ' & $T_FILECOUNT ,$N_TFILE)
         EndIf
      Wend
      FileClose($N_SEARCH)
   Wend
   $T_FILENAMES  = StringTrimRight($T_FILENAMES,1)
   $N_OFILE = StringSplit($T_FILENAMES,@CR)
   Return( $N_OFILE )
EndFunc   ;==>_GetFileList

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

Worked like a charm!

what is the difference between release and beta that make the script work?

Share this post


Link to post
Share on other sites

Worked like a charm!

what is the difference between release and beta that make the script work?

The beta has more functions and functionality than the release version. It's what is used to determine what's going to be in the next released version.

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Thanks for all of your help, i have included my final script incase anyone wants to have a nice GUI that searches folders recursively for music.

AutoIT___Search_Media.rar

Share this post


Link to post
Share on other sites

Jdeb this is working great but how can I make this work for more than 1 directory drive....I need for c:\ and d:\ but how can i do this? :-??

Share this post


Link to post
Share on other sites

Please i really need help

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Hi Jos,

it works famous. Thanks

In case to need only directories, I've made an enlargement to use your function with flag DIR_ONLY.

I hope you like that.

; AutoIt Version: 3.0
; Language:       English
; Platform:       Win9x/NT/XP
; Author:         jos van der Zande
;
; Find files in directory and subdirectories and return it in an Array, all coded in Autoit3
;
Dim $FILES
Dim $DIR="C:\Programme\autoit3\"  ; specify the directory to search
Dim $FILEMASK="n"                 ; specify the filemask ("n" for GetDirOnly)
$FILES = _GetFileList($DIR, $FILEMASK, 1)   ; _GetFileList($DIR, $FILEMASK [, Flag])  Flag GetFile(Default) = 0 , GetDirOnly = 1
For $X = 0 To UBound($FILES)-1
   MsgBox(0,'test:' & $X,$FILES[$X])
Next 
Exit
;********************************************************************************
;Recursive search for filemask
;********************************************************************************

Func _GetFileList($T_DIR,$T_MASK,$DIR_ONLY=0)
   Dim $N_DIRNAMES[200000] ; max number of directories that can be scanned
   Local $N_DIRCOUNT = 0
   Local $N_FILE
   Local $N_SEARCH
   Local $N_TFILE
   Local $N_OFILE
   Local $T_FILENAMES
   Local $T_FILECOUNT
   Local $T_DIRCOUNT = 1
   ; check Filemask \ to let File-Array empty by GetDirOnly
   If $T_MASK = "n" Then $T_MASK = "*.no"
   ; remove the end \ If specified
   If StringRight($T_DIR,1) = "\" Then $T_DIR = StringTrimRight($T_DIR,1)
   $N_DIRNAMES[$T_DIRCOUNT] = $T_DIR
   ; Exit if base dir doesn't exists
   If Not FileExists($T_DIR) Then Return 0
   ; keep on looping until all directories are scanned
   While $T_DIRCOUNT > $N_DIRCOUNT
      $N_DIRCOUNT = $N_DIRCOUNT + 1
      ; find all subdirs in this directory and save them in a array
      $N_SEARCH = FileFindFirstFile($N_DIRNAMES[$N_DIRCOUNT] & "\*.*") 
      While 1
         $N_FILE = FileFindNextFile($N_SEARCH)
         If @error Then ExitLoop
         ; skip these references
         If $N_FILE = "." Or $N_FILE = ".." Then ContinueLoop
         $N_TFILE = $N_DIRNAMES[$N_DIRCOUNT] & "\" & $N_FILE
         ; if Directory than add to the list of directories to be processed
         If StringInStr(FileGetAttrib( $N_TFILE ),"D") > 0 Then
            $T_DIRCOUNT = $T_DIRCOUNT + 1
            $N_DIRNAMES[$T_DIRCOUNT] = $N_TFILE
         EndIf
      Wend
      FileClose($N_SEARCH)      ; find all Files that mtach the MASK
      $N_SEARCH = FileFindFirstFile($N_DIRNAMES[$N_DIRCOUNT] & "\" & $T_MASK ) 
      If $N_SEARCH = -1 Then ContinueLoop
      While 1
         $N_FILE = FileFindNextFile($N_SEARCH)
         If @error Then ExitLoop
         ; skip these references
         If $N_FILE = "." Or $N_FILE = ".." Then ContinueLoop
         $N_TFILE = $N_DIRNAMES[$N_DIRCOUNT] & "\" & $N_FILE
         ; if Directory than add to the list of directories to be processed
         If StringInStr(FileGetAttrib( $N_TFILE ),"D") = 0 Then
            $T_FILENAMES  = $T_FILENAMES & $N_TFILE & @CR
            $T_FILECOUNT = $T_FILECOUNT + 1
            ;MsgBox(0,'filecount ' & $T_FILECOUNT ,$N_TFILE)
         EndIf
      Wend
      FileClose($N_SEARCH)
    Wend
    If $DIR_ONLY = 0 Then
      $T_FILENAMES  = StringTrimRight($T_FILENAMES,1)
      $N_OFILE = StringSplit($T_FILENAMES,@CR)
      Return( $N_OFILE )
    Else
      ReDim $N_DIRNAMES[$N_DIRCOUNT+1]
      $N_DIRNAMES[0] = $N_DIRCOUNT
      Return $N_DIRNAMES
    EndIf
EndFunc   ;==>_GetFileList
Edited by BugFix

Best Regards BugFix  

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0