Search the Community
Showing results for tags 'recursive'.
-
Hi all, I'm trying to make a listing of all files in subdirectories on a specific level in a folder structure. Let me explain, visually, this will help things a lot. I have a folder structure like this: ROOT |--- SUBDIR 1 | |---- SUBDIR 1.1 | |----- SUBDIR 1.1.1 | |---- File1.ext | |----- SUBDIR 1.1.2 | |---- File2.ext | |----- SUBDIR 1.1.3 | |---- File2.ext | |----- SUBDIR 1.1.4 | |---- File2.ext | |----- SUBDIR 1.1.5 | |---- File2.ext | |---- SUBDIR 1.2 | |----- SUBDIR 1.2.1 | ..... | |---- SUBDIR 1.3 .... I use _FileListToArrayRec twice: - once to make an array of the specific directories I should be working at: I need all files on the x.x level, so it will go just until that depth using a negative integer for $iRecur - once again to create an array of all files found under that directory and its subdirectories (level x.x.x\files...) What happens now is that _FileListToArrayRec will always include all levels before the maximum depth is reached. The result would look like this Row 0 15 Row 1 Root\Subdir 1 Row 2 Root\Subdir 2 Row 3 Root\Subdir 3 Row 4 Root\Subdir 1\Subdir 1.1 Row 5 Root\Subdir 1\Subdir 1.2 Row 6 Root\Subdir 1\Subdir 1.3 ... Needless to say that when my second function iterates over this array, it will find all files twice. Once on the x level, once again on the x.x level. There is no way for me not to use the recursive option in the second iteration, since the files are actually in a subdirectory there. Where are the wizards of programming logic here? Since I can't seem to find a comprehensible or easily implementable solution for this issue. Thanks in advance and kind regards, Jan
-
I'm writing a recursive decent parser in Autoit! The programming language i'm making is called HighLevel. I'm doing this for learning purposes, because it's fun and because I can implement it into my other project: Fullscreen Console With custom programming language! It's not easy... In Autoit you don't have objects like in Java or Visual Basic, so I had to figure out a way to still convert the code to an abstract syntax tree. I used nested array's and array based dictionary's instead of objects. The code is still very dirty and I need to make a lot of modifications but if you're careful with testing you'll see what it can do already. Console window Because this code eventually will get implemented into my console project I crafted a nice little console window (with a custom sci-fi looking theme, yeah i was a little bored haha). {ESC} is your panic button for now, it terminates the script completely. If you get an error while opening a script the text will turn red. To minimize it press the blue button, to close it use the red one, to drag the gui just grab it on one of the sides. The console window will display what you write to it with your "HighLevel-script" and some additional information: How to test it: Download: HighLevel.Au3, Debug.Au3 (includes a function to display nested arrays for debugging), GUI.bmp (for the console) Compile the Autoit code to EXE. The GUI.bmp must be in the same folder as the EXE file! Write a HighLevel-script (text file) and drag it into the compiled autoit-exe. The custom made little console window will pop up in the left top corner of your screen and your HighLevel-script (the text file) will be interpreted and executed. The Language: exit script: Abort show / hide the console: Show Hide write to/clear the console: Write 'this is a ''string''!' Clear variables: test_var_1 = 123 some_list = ['a', 5, true] some_list[1] = 3 math = 1 + 2 * 3 / 4 - -5 & test_var beep (under construction): Beep F, optD wait X seconds: Wait X Messages: Message 'Hello World!' move/click the mouse: Move X, Y Click send keys (under construction): Send 'HighLevel', True if's: If false ElseIf true # this part will run Else End subs: Sub X # do stuff End Call X for loops: For X = 1 to 10 # X iterates End Values: Input 'Give me input' Random YesNo 'yes or no' operators: + - * / & > = ! < ( ) And Not Or Example script: # my first HighLevel script message 'Hello World!' message 'Lets write to the console...' clear # clear the console... list = ['a', 16, true] for i = 0 to 2 write list[i] wait 1 end sub test if YesNo 'would you like to quit?' message 'Goodbye!' abort else write 1 + 2 * 3 & ' math!' end end call test test script.HighLevel GUI.bmp Debug.au3 HighLevel.au3
-
- interpreter
- parser
-
(and 3 more)
Tagged with:
-
Hi Guys/Gals, I'm using the AD UDF to interogate our AD (the computers section, which we have under an OU of managed), what I'm trying to do (and failing horribly) is recurse through the sub OU's and place them inside a treeview container. e.g Access | |-Teachers |- Students |-Office but I can't get it to go past the first sub OU, and it's creating duplicates... my code is below #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.8.1 Author: myName Script Function: Template AutoIt script. #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here #include <GUIConstantsEx.au3> #include <ListViewConstants.au3> #include <ProgressConstants.au3> #include <TreeViewConstants.au3> #include <WindowsConstants.au3> #include <AD.au3> $ADToolbox = GUICreate("ADToolbox", 1245, 789, 192, 124) $Root = GUICtrlCreateTreeView(8, 8, 241, 769, BitOR($GUI_SS_DEFAULT_TREEVIEW,$WS_BORDER)) $Itemspane = GUICtrlCreateListView("", 256, 8, 801, 681) $taskprog = GUICtrlCreateProgress(256, 696, 801, 25, BitOR($PBS_SMOOTH,$PBS_MARQUEE,$WS_BORDER)) GUISetState(@SW_SHOW) _AD_Open() Global $aOUs = _AD_GetAllOUs("OU=Computers,OU=Managed,DC=SCHOOL,DC=LOCAL", "", 0) If @error > 0 Then MsgBox(48, "Active Directory Functions", "No OUs could be found") Else $iCount = 2 Do $sOU = "ou=" & StringReplace($aOUs[$iCount - 1][0], "\", ",ou=") & "," & $sAD_DNSDomain $trunk = stringsplit($sOU, ",") if $trunk[0] > 4 Then $leafcount = 0 $branchno = 0 do if $branchno = 0 then if $trunk[5] <> "DC=Local" and $trunk[5] <> "DC=SCHOOL" then $branch = GUICtrlCreateTreeViewItem($trunk[5], $root) $branchno = 1 $leafcount = $leafcount + 1 else $leafcount = $leafcount + 1 EndIf Else $count = 0 $leafname = 0 do if $leafname = 0 Then if $trunk[6] <> "DC=Local" and $trunk[6] <> "DC=SCHOOL" then $leaf = GUICtrlCreateTreeViewItem($trunk[6], $Branch) $leafname = 1 $count = $count + 1 else $count = $count + 1 $leafname = 0 EndIf endif until $count = $trunk[0] $leafname=0 $branchno = 0 $count = 0 EndIf until $leafcount = $trunk[0] $leafcount = 0 $branchno = 0 EndIf $iCount=$iCount+1 until $iCount = $aOUs[0][0] EndIf While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd thanks in advance RichE
-
I know there's already several of these types of functions around the forum but there were some things I wanted to do different, so I wrote my own. In the tests I've done this appears to be working fine, but I'd appreciate a second look. The error returns and the first three parameters are the same as the vanilla _FileListToArray, but there are a couple new flags, and two new parameters. The new flags include: - enabling recursion (4) - disabling file count in element [0] (8) - enabling full path returns (16). The new parameters are: - $sCallback - this is the name of a function you want to run on each loop, it is passed an array with data relating to the current file search in the loop. If the callback function returns 0 then the item is processed normally. If it returns 1 the item is skipped (this can be used to skip entire folders being processed). If it returns -1 the entire function errors out with -1 and @extended is set to the callback function's @extended value. - $sCallbackUserParam - just an extra parameter that can be passed through to the callback function. Example with callback: #include <Array.au3> #include <_FileListToArrayRecursive.au3> Global $sWFile _FileListToArrayRecursive(@DesktopDir, '*', 4, '_Callback', 'Wfile') If @error = -1 And @extended = 42 Then MsgBox(0, '', 'You have a W file:' & @LF & $sWFile) Else MsgBox(0, '', 'No files/folders that start with W exist.') EndIf Global $aReadOnly = _FileListToArrayRecursive(@DesktopDir, '*', 1+4, '_Callback', 'readonly') Global $aEmpty = _FileListToArrayRecursive(@DesktopDir, '*', 1+4, '_Callback', 'empty') _ArrayDisplay($aReadOnly) _ArrayDisplay($aEmpty) Func _Callback($aParams) Switch $aParams[5] Case 'Wfile' If StringLeft($aParams[2], 1) == 'W' Then $sWFile = $aParams[1] & $aParams[2] Return SetExtended(42, -1) EndIf Case 'empty' If Not $aParams[3] Then If FileGetSize($aParams[0] & $aParams[1] & $aParams[2]) Then Return 1 EndIf Case 'readonly' If Not $aParams[3] Then If Not StringInStr(FileGetAttrib($aParams[0] & $aParams[1] & $aParams[2]), 'R') Then Return 1 EndIf EndSwitch EndFunc #include-once ; #FUNCTION# ==================================================================================================================== ; Name...........: _FileListToArrayRecursive ; Description ...: Lists files and/or folders in a specified path recursively ; Syntax.........: _FileListToArrayRecursive($sPath[, $sFilter = '*'[, $iFlag = 0[, $sCallback = ''[, $sCallbackUserParam = '' ] ] ] ] ) ; Parameters ....: $sPath - Path to search ; $sFilter - Optional: the filter to use, default is * ; $iFlag - Optional: specifies options about return, add flags together ; |$iFlag = 0 (Default) Return both files and folders ; |$iFlag = 1 Return files only ; |$iFlag = 2 Return folders only ; |$iFlag = 4 Search subfolders (Enable recursion) ; |$iFlag = 8 Make array 0-based (Disable return count in first element) ; |$iFlag = 16 Return full paths (default only returns from the search folder down) ; $sCallback - Optional: function to call on each loop. See remarks for details (default: none) ; $sCallbackUserParam - Optional: a parameter to pass to the Callback function (default: none) ; Return values .: @Error - 1 = Path not found or invalid ; |2 = Invalid $sFilter ; |3 = Invalid $iFilter ; |4 = No files found or folder inaccessible ; |5 = No files found or folder inaccessible ; |-1 = Callback function returned -1 ; Author ........: Rob Saunders (therks at therks dot com) ; Modified.......: ; Remarks .......: If $sCallback is defined the function will be called on each loop and it can alter what files are recorded ; in the return array. The Callback function runs on every file result because it is called *before* the flag ; filter for files/folders ($iFlag 1 or 2). ; Return 0 = Item is added (depending on $iFlag 1 or 2) ; Return 1 = Item is skipped (note: if you skip a folder it will not be searched either) ; Return -1 = Stop searching. Main func returns false, @error = -1, @extended = Callback's @extended value ; The function is passed one parameter, a 6 item array with values as follows: ; [0] root search folder ; [1] current sub folder ; [2] current filename match ; [3] 1 if file is a folder; 0 if not ; [4] current file count ; [5] $sCallbackUserParam ; ; Related .......: _FileListToArray ; Link ..........: ; Example .......: ; Note ..........: Some parts from original function (by SolidSnake) and _FileListToArrayEx (by DXRW4E) ; =============================================================================================================================== Func _FileListToArrayRecursive($sPath, $sFilter = '*', $iFlag = 0, $sCallback = '', $sCallbackUserParam = '') Local Const $FL_FILES = 1, $FL_FOLDERS = 2, $FL_RECURSE = 4, $FL_NOCOUNT = 8, $FL_FULLPATH = 16 If Not StringInStr(FileGetAttrib($sPath), 'D') Then Return SetError(1, 1, '') If StringRegExp($sFilter, '[\\/:><\|]|(?s)\A\s*\z') Then Return SetError(2, 2, '') If $iFlag < 0 Or $iFlag > 1+2+4+8+16 Then Return SetError(3, 3, '') $sPath = StringRegExpReplace($sPath, '[\\/]+$', '') & '\' Local $sFileTrack, $iFileCount, $hParentSearch, $hSearch, $hSubCheck, $sSubDir, $sFile, $iIsFolder, $sRegExFilter, $sAddFullPath, _ $iReturnFolders, $iReturnFiles, $iRecurse, $iReturnCount, $iSortOffset, _ $aCallbackData[6], $vCallbackReturn, $iCallbackExt $aCallbackData[5] = $sCallbackUserParam If BitAND($iFlag, $FL_FULLPATH) Then $sAddFullPath = $sPath If BitAND($iFlag, $FL_RECURSE) Then $iRecurse = 1 If StringReplace($sFilter, '*', '') Then ; If we ARE recursing, and the filter is something besides just * then initialize the regex filter $sRegExFilter = '(?i)^' & StringRegExpReplace(StringReplace(StringRegExpReplace($sFilter, '(\.|\||\+|\(|\)|\{|\}|\[|\]|\^|\$|\\)', "\\$1"), '?', '.'), '\*+', '.*') & '$' $sFilter = '*' EndIf EndIf If BitAND($iFlag, $FL_FILES) Then $iReturnFiles = 1 ElseIf BitAND($iFlag, $FL_FOLDERS) Then $iReturnFolders = 1 Else $iReturnFiles = 1 $iReturnFolders = 1 EndIf If BitAND($iFlag, $FL_NOCOUNT) Then $iReturnCount = 2 ; Param for StringSplit $iSortOffset = 0 EndIf $hParentSearch = FileFindFirstFile($sPath & $sSubDir & $sFilter) If $hParentSearch = -1 Then Return SetError(4, 4, '') $hSearch = $hParentSearch While 1 $sFile = FileFindNextFile($hSearch) If @error Then If $hParentSearch = $hSearch Then ExitLoop FileClose($hSearch) $hSearch -= 1 $sSubDir = StringLeft($sSubDir, StringInStr(StringTrimRight($sSubDir, 1), '\', 0, -1)) ContinueLoop EndIf $iIsFolder = @extended If $sCallback Then $aCallbackData[0] = $sPath $aCallbackData[1] = $sSubDir $aCallbackData[2] = $sFile $aCallbackData[3] = $iIsFolder $aCallbackData[4] = $iFileCount $vCallbackReturn = Call($sCallback, $aCallbackData) If @error = 0xDEAD And @extended = 0xBEEF Then FileClose($hSearch) FileClose($hParentSearch) Return SetError(5, 5, '') ElseIf $vCallbackReturn = -1 Then $iCallbackExt = @extended FileClose($hSearch) FileClose($hParentSearch) Return SetError(-1, $iCallbackExt, '') ElseIf $vCallbackReturn Then ContinueLoop EndIf EndIf If $iRecurse Then If ($iIsFolder And $iReturnFolders) Or (Not $iIsFolder And $iReturnFiles) Then If Not $sRegExFilter Or ($sRegExFilter And StringRegExp($sFile, $sRegExFilter)) Then $sFileTrack &= '|' & $sAddFullPath & $sSubDir & $sFile $iFileCount += 1 EndIf EndIf If $iIsFolder Then $hSubCheck = FileFindFirstFile($sPath & $sSubDir & $sFile & '\' & $sFilter) If $hSubCheck = -1 Then ContinueLoop $sSubDir &= $sFile & '\' $hSearch = $hSubCheck EndIf Else If ($iIsFolder And $iReturnFolders) Or (Not $iIsFolder And $iReturnFiles) Then $sFileTrack &= '|' & $sAddFullPath & $sSubDir & $sFile $iFileCount += 1 EndIf EndIf WEnd FileClose($hParentSearch) Local $aReturnList = StringSplit(StringTrimLeft($sFileTrack, 1), '|', $iReturnCount) If @error Then Return SetError(4, 4, '') Return $aReturnList EndFunc I'm still working on this as time goes by so the most up to date version can be found in my dropbox: http://db.tt/OqNgumLK
- 1 reply
-
- _FileListToArray
- Recursive
-
(and 2 more)
Tagged with: