Sign in to follow this  
Followers 0
RAMMRODD

Possible to read files in a directory 3 or 4 folders down?

5 posts in this topic

I have another post about my idea to make a file name correction program. There is already one made but not I need a faster way to do what I wanna do. The program works great and it can take 01-Rob-Zombie-Living-Dead-Girl.mp3 and change it to Living Dead Girl.mp3 (which is what I want) but the script has to be in the folder with the mp3's in order for them to be changed. My files are in this structure:

Music folder ->Artist->CD Name->Actualfile.mp3

is there any way to make autoit read a few undefined files deep instead of just in the folder its in? I was thinking something something like:

Script here->*(wildcard)->*(wildcard)->*.mp3

Hoping that autoit would look a few folders down for the file but my attempts have failed.

Is this possible? or something like it?

Share this post


Link to post
Share on other sites



RAMMRODD,

Try searching for "+recursive +file +search". There are many scripts on the forums which will delve deep into your folder structure.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

xZZTx has what I need. Sweet!

$Dir = @ScriptDir
$Dr1 = $Dir
$Dr2 = 0
dim $Dr[100]
$A = FileFindFirstFile("*.*")
while 1
$B = FileFindNextFile($A)
$C = StringSplit(FileGetLongName($B,1),".")
If @error = 0 Then
If $C[0] >= 2 Then
If $C[2] = "mp3"Then                               ;I put this in but its still adding .txt and .au3
      FileWriteLine("text.zzt",$Dir&"\"&$B)
  Else         
      msgbox(1,"nothing",$b)
      $Dr[$Dr[0]] = $Dr3&"\"&$B

   
EndIf
EndIf
EndIf
    If $C[0] = 1 And $B = Not "" Then
        If $Dr2 = 1 Then
            $Dr[0] += 1
        Else
        $Dr3 = $Dir
        $Dr2 = 1
        $Dir = $Dir&"\"&$B
        EndIf
    EndIf
    If $B = "" Then
        $Dr2 = 0
        If $Dir = $Dr1 Then
            If $Dr[0] = Not 0 Then
                $Dir = $Dr[$Dr[0]]
                $Dr[0] -= 1
                $Dr2 = 0
            Else
            ExitLoop
            EndIf
        EndIf
        $A = FileFindFirstFile($Dir&"\*.*")
        $Dr1 = $Dir
        $B = ""
    EndIf
WEnd

I commented part that I changed. I thought changing the original to just if *function*= "mp3" then write to file, it would just copy mp3 but it does all still. Any info on why?

Edited by RAMMRODD

Share this post


Link to post
Share on other sites

RAMMRODD,

With apologies in advance to xZZTx, I have severe reservations over the utility of code you posted.

My main concern is that I see a FileFindFirstFile function in a loop with no corresponding CloseFile. From the Help file for FileFindFirstFile:

"When you have finished searching with the FileFind... functions you must call FileClose() to release the search handle."

Each process is limited to 512 handles, so I could see this code very rapidly running out of handles. My own music folder has 777 folders and subfolders, so this script would crash for sure if I used it to list my mp3s. :(

Given the above, I have no real inclination to debug this script. But you might be interested in these 2 versions of my current recursive file/folder finder. I have written them as formal include files, so just save them to your working folder and put #include"file-name" at the top of your script to use the function. I hope the instructions are self-explanatory and I have commented liberally so you should be able to follow what is going on.

The first uses recursion - which as a hobbyist coder does not concern me at all, although professionals throw their hands up in horror. :(

#include-once

; #FUNCTION# ====================================================================================================================
; Name...........:_FileListToArray_Rec
; Description ...: Lists files and\or folders in a specified path with optional recursion. Compatible with_FileListToArray syntax
; Syntax.........:_FileListToArray_Rec($sPath[, $sInclude_List = "*"[, $iReturn = 0[, $iRecur = 0[, $sExclude_List = ""[, $iFullPath = 0]]]]])
; Parameters ....: $sPath   - Initial path used to generate filelist
;                  $sInclude_List - Optional: the filter for included results (default is "*"). Multiple filters must be separated by ";"
;                  $iReturn   - Optional: specifies whether to return files, folders or both
;                  |$iReturn=0 (Default) Return both files and folders
;                  |$iReturn=1 Return files only
;                  |$iReturn=2 Return folders only
;                  $iRecur  - Optional: specifies whether to search in subfolders
;                  |$iRecur=0 (Default) Do not search in subfolders
;                  |$iRecur=1 Search in subfolders
;                  $sExclude_List - Optional: the filter for excluded results (default is ""). Multiple filters must be separated by ";"
;                  $iFullPath  - Optional: specifies path of result string
;                  |$iFullPath=0 (Default) Initial path not included
;                  |$iFullPath=1 Initial path included
;                  |$iFullPath=2 File/folder name only
; Requirement(s).: v3.3.1.1 or higher
; Return values .: Success:  One-dimensional array made up as follows:
;                  |$array[0] = Number of Files\Folders returned
;                  |$array[1] = 1st File\Folder
;                  |$array[2] = 2nd File\Folder
;                  |...
;                  |$array[n] = nth File\Folder
;                   Failure: Null string and @error set:
;                  |1 = Path not found or invalid
;                  |2 = Invalid $sInclude_List
;                  |3 = Invalid $iReturn
;                  |4 = Invalid $iRecur
;                  |5 = Invalid $sExclude_List
;                  |6 = Invalid $iFullPath
;                  |7 = No file/folder found
; Author ........: Melba23 using SRE code from forums
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; Yes
; ===============================================================================================================================
Func _FileListToArray_Rec($sPath, $sInclude_List = "*", $iReturn = 0, $iRecur = 0, $sExclude_List = "", $iFullPath = 0)

    Local $asReturnList[1] = [0], $sInitialPath, $sInclude_List_Mask, $sExclude_List_Mask

    ; Check valid path
    If Not FileExists($sPath) Then Return SetError(1, 1, "")
    ; Ensure trailing \
    If StringRight($sPath, 1) <> "\" Then $sPath = $sPath & "\"
    ; Set value for original path
    $sInitialPath = $sPath
    ; Determine Filter mask for SRE check
    If StringRegExp($sInclude_List, '\\|/|:|\"|\<|\>|\|') Then Return SetError(2, 2, "") ; Check if invalid characters within $sInclude_List
    $sInclude_List = StringReplace(StringStripWS(StringRegExpReplace($sInclude_List, '\s*;\s*', ';'), 3), ';', '|') ; Strip $sInclude_List of WS and insert |
    $sInclude_List_Mask = '(?i)^' & StringReplace(StringReplace(StringReplace($sInclude_List, '.', '\.'), '*', '.*'), '?', '.') & "\z" ; Convert $sInclude_List to SRE pattern
    ; Determine Exclude mask for SRE check
    If $sExclude_List = "" Then
        $sExclude_List_Mask = ':' ; Set unmatchable mask
    Else
        If StringRegExp($sExclude_List, '\\|/|:|\"|\<|\>|\|') Then Return SetError(5, 5, "") ; Check if invalid characters within $sExclude_List
        $sExclude_List = StringReplace(StringStripWS(StringRegExpReplace($sExclude_List, '\s*;\s*', ';'), 3), ';', '|') ; Strip $sExclude_List of WS and insert |
        $sExclude_List_Mask = '(?i)^' & StringReplace(StringReplace(StringReplace($sExclude_List, '.', '\.'), '*', '.*'), '?', '.') & "\z" ; Convert $sExclude_List to SRE pattern
    EndIf
    ; Verify other parameter values
    If Not ($iReturn = 0 Or $iReturn = 1 Or $iReturn = 2) Then Return SetError(3, 3, "")
    If Not ($iRecur = 0 Or $iRecur = 1) Then Return SetError(4, 4, "")
    If Not ($iFullPath = 0 Or $iFullPath = 1 Or $iFullPath = 2) Then Return SetError(6, 6, "")

    ; Search - $sRelativePath = ""
    _FLTA_Rec_Search($sPath, $sInitialPath, $sInclude_List_Mask, $iReturn, $iRecur, $sExclude_List_Mask, $iFullPath, $asReturnList)

    ; Check if array filled
    If $asReturnList[0] = 0 Then Return SetError(7, 7, "")
    ; Remove unused array elements from last ReDim
    ReDim $asReturnList[$asReturnList[0] + 1]

    Return $asReturnList

EndFunc   ;==>_FileListToArray_Rec

; #INTERNAL_USE_ONLY#============================================================================================================
; Name...........: _FLTA_Rec_Search
; Description ...: Searches folder for files and then optionally searches recursively in subfolders
; Syntax.........: _FLTA_Rec_Search($sCurrentPath, $sInitialPath, $sInclude_List, $iReturn, $iRecur, $sExclude_List, $sFullPath, ByRef $asReturnList)
; Parameters ....: $sCurrentPath - Current path to search
;                  $sInitialPath - Initial path used to generate filelist as set in_FileListToArray_Rec
;                  $sInclude_List_Mask - As set in_FileListToArray_Rec
;                  $iReturn - As set in_FileListToArray_Rec
;                  $iRecur - As set in_FileListToArray_Rec
;                  $sExclude_List_Mask - As set in_FileListToArray_Rec
;                  $iFullPath - As set in_FileListToArray_Rec
;                  $asReturnList - Array containing found files/folders
; Return values .: None
; Author ........: Melba23 based on _FileListToArray by SolidSnake with SRE code from forums
; Modified.......:
; Remarks .......: This function is used internally by_FileListToArray_Rec.
; Related .......:
; Link ..........;
; Example .......;
; ===============================================================================================================================
Func _FLTA_Rec_Search($sCurrentPath, $sInitialPath, $sInclude_List_Mask, $iReturn, $iRecur, $sExclude_List_Mask, $iFullPath, ByRef $asReturnList)

    Local $hSearch, $sName, $fFolder, $sReturnPath = ""

    ; Search folder
    $hSearch = FileFindFirstFile($sCurrentPath & "*")
    If $hSearch = 0 Then Return ; Folder empty
    ; Set path to add
    Switch $iFullPath
        Case 0 ; Initial path not included
            $sReturnPath = StringReplace($sCurrentPath, $sInitialPath, "")
        Case 1 ; Initial path included
            $sReturnPath = $sCurrentPath
        ; Case 2 ; Name only so leave as ""
    EndSwitch
    While 1
        $sName = FileFindNextFile($hSearch)
        $fFolder = @extended ; @extended set if $sName is folder in 3.3.1.1 +
        If @error Then ExitLoop ; End of folder
        ; Check file/folder type against required return value and file/folder name against Include/Exclude masks
        If $fFolder + $iReturn <> 2 And StringRegExp($sName, $sInclude_List_Mask) And Not StringRegExp($sName, $sExclude_List_Mask) Then
            ; Increase item count
            $asReturnList[0] += 1
            ; Double array size if too small (fewer ReDim needed)
            If UBound($asReturnList) <= $asReturnList[0] Then ReDim $asReturnList[UBound($asReturnList) * 2]
            ; Add required path to file/folder name and add to array
            $asReturnList[$asReturnList[0]] = $sReturnPath & $sName
        EndIf
        ; If recursive then search folder
        If $fFolder And $iRecur Then _FLTA_Rec_Search($sCurrentPath & $sName & "\", $sInitialPath, $sInclude_List_Mask, $iReturn, $iRecur, $sExclude_List_Mask, $iFullPath, $asReturnList)
    WEnd
    FileClose($hSearch)

EndFunc   ;==>_FLTA_Rec_Search

The second uses a folder stack, which is how "real" programmers do it >_< . It is very slightly faster, but does return the files/folders in a slightly mixed up order rather then nicely arranged:

; #FUNCTION# ====================================================================================================================
; Name...........: _FileListToArray_Stack
; Description ...: Lists files and\or folders in a specified path with optional recursion.  Compatible with existing _FileListToArray syntax
; Syntax.........: _FileListToArray_Stack($sPath[, $sInclude_List = "*"[, $iReturn = 0[, $fRecur = 0[, $sExclude_List = ""[, $iFullPath = 0]]]]])
; Parameters ....: $sPath   - Initial path used to generate filelist
;                  $sInclude_List - Optional: the filter for included results (default is "*"). Multiple filters must be separated by ";"
;                  $iReturn   - Optional: specifies whether to return files, folders or both
;                  |$iReturn=0 (Default) Return both files and folders
;                  |$iReturn=1 Return files only
;                  |$iReturn=2 Return folders only
;                  $fRecur  - Optional: specifies whether to search in subfolders
;                  |$fRecur=0 (Default) Do not search in subfolders
;                  |$fRecur=1 Search in subfolders
;                  $sExclude_List - Optional: the filter for excluded results (default is ""). Multiple filters must be separated by ";"
;                  $iFullPath  - Optional: specifies path of result string
;                  |$iFullPath=0 (Default) Initial path not included
;                  |$iFullPath=1 Initial path included
;                  |$iFullPath=2 File/folder name only
; Requirement(s).: v3.3.1.1 or higher
; Return values .: Success:  One-dimensional array made up as follows:
;                  |$array[0] = Number of Files\Folders returned
;                  |$array[1] = 1st File\Folder
;                  |$array[2] = 2nd File\Folder
;                  |...
;                  |$array[n] = nth File\Folder
;                   Failure: Null string and @error set:
;                  |1 = Path not found or invalid
;                  |2 = Invalid $sInclude_List
;                  |3 = Invalid $iReturn
;                  |4 = Invalid $fRecur
;                  |5 = Invalid $sExclude_List
;                  |6 = Invalid $iFullPath
;                  |7 = No file/folder found
; Author ........: Melba23 using SRE code from forums
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; Yes
; ===============================================================================================================================
Func _FileListToArray_Stack($sInitialPath, $sInclude_List = "*", $iReturn = 0, $fRecur = 0, $sExclude_List = "", $iFullPath = 0)

    Local $asReturnList[1] = [0], $asFolderList[3] = [1], $sInclude_List_Mask, $sExclude_List_Mask
    Local $sCurrentPath, $hSearch, $sReturnPath = "", $sName, $fFolder

    ; Check valid path
    If Not FileExists($sInitialPath) Then Return SetError(1, 1, "")
    ; Ensure trailing \
    If StringRight($sInitialPath, 1) <> "\" Then $sInitialPath = $sInitialPath & "\"
    ; Add path to folder list
    $asFolderList[1] = $sInitialPath

    ; Determine Filter mask for SRE check
    If StringRegExp($sInclude_List, '\\|/|:|\"|\<|\>|\|') Then Return SetError(2, 2, "") ; Check if invalid characters within $sInclude_List
    $sInclude_List = StringReplace(StringStripWS(StringRegExpReplace($sInclude_List, '\s*;\s*', ';'), 3), ';', '|') ; Strip $sInclude_List of WS and insert |
    $sInclude_List_Mask = '(?i)' & StringReplace(StringReplace(StringReplace($sInclude_List, '.', '\.'), '*', '.*'), '?', '.') & "\z" ; Convert $sInclude_List to SRE pattern

    ; Determine Exclude mask for SRE check
    If $sExclude_List = "" Then
        $sExclude_List_Mask = ':' ; Set unmatchable mask
    Else
        If StringRegExp($sExclude_List, '\\|/|:|\"|\<|\>|\|') Then Return SetError(5, 5, "") ; Check if invalid characters within $sExclude_List
        $sExclude_List = StringReplace(StringStripWS(StringRegExpReplace($sExclude_List, '\s*;\s*', ';'), 3), ';', '|') ; Strip $sExclude_List of WS and insert |
        $sExclude_List_Mask = '(?i)' & StringReplace(StringReplace(StringReplace($sExclude_List, '.', '\.'), '*', '.*'), '?', '.') & "\z" ; Convert $sExclude_List to SRE pattern
    EndIf

    ; Verify other parameter values
    If Not ($iReturn = 0 Or $iReturn = 1 Or $iReturn = 2) Then Return SetError(3, 3, "")
    If Not ($fRecur = 0 Or $fRecur = 1) Then Return SetError(4, 4, "")
    If Not ($iFullPath = 0 Or $iFullPath = 1 Or $iFullPath = 2) Then Return SetError(6, 6, "")

    ; Search in listed folders
    While $asFolderList[0] > 0

        ; Set path to search
        $sCurrentPath = $asFolderList[$asFolderList[0]]
        ; Reduce folder array count
        $asFolderList[0] -= 1
        ; Get search handle
        $hSearch = FileFindFirstFile($sCurrentPath & "*")
        ; If folder empty move to next in list
        If $hSearch = -1 Then ContinueLoop

        ; Determine path to add to file/folder name
        Switch $iFullPath
            Case 0 ; Initial path not included
                $sReturnPath = StringReplace($sCurrentPath, $sInitialPath, "")
            Case 1 ; Initial path included
                $sReturnPath = $sCurrentPath
            ; Case 2 ; Name only so leave as ""
        EndSwitch

        ; Search folder
        While 1
            $sName = FileFindNextFile($hSearch)
            ; Check for end of folder
            If @error Then ExitLoop
            ; Check for subfolder - @extended set in 3.3.1.1 +
            $fFolder = @extended

            ; If recursive search, add subfolder to folder list
            If $fRecur And $fFolder Then
                ; Increase folder array count
                $asFolderList[0] += 1
                ; Double folder array size if too small (fewer ReDim needed)
                If UBound($asFolderList) <= $asFolderList[0] + 1 Then ReDim $asFolderList[UBound($asFolderList) * 2]
                ; Add subfolder to list
                $asFolderList[$asFolderList[0]] = $sCurrentPath & $sName & "\"
            EndIf

            ; Check file/folder type against required return value and file/folder name against Include/Exclude masks
            If $fFolder + $iReturn <> 2 And StringRegExp($sName, $sInclude_List_Mask) And Not StringRegExp($sName, $sExclude_List_Mask) Then
                ; Increase return array count
                $asReturnList[0] += 1
                ; Double return array size if too small (fewer ReDim needed)
                If UBound($asReturnList) <= $asReturnList[0] Then ReDim $asReturnList[UBound($asReturnList) * 2]
                ; Add required path to file/folder name and add to array
                $asReturnList[$asReturnList[0]] = $sReturnPath & $sName
            EndIf
        WEnd

        ; Close current search
        FileClose($hSearch)

    WEnd

    ; Check if any file/folders to return
    If $asReturnList[0] = 0 Then Return SetError(7, 7, "")
    ; Remove unused return array elements from last ReDim
    ReDim $asReturnList[$asReturnList[0] + 1]

    Return $asReturnList

EndFunc   ;==>_FileListToArray_Stack

Try them both and see which you prefer. Any comments welcome. Feel free to use all or any of the code in your own scripts.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Who do we talk to to see these search scripts get a sticky?

Impressive work.


:blink: What just happened?

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