RaySS Posted December 22, 2015 Share Posted December 22, 2015 In a high-level directory, some subdirectories contain files with the .fit file extension. I want to capture the names of only those subdirectories which contain .fit files. Here's a representative fragment of my code:#include <MsgBoxConstants.au3> #include <File.au3> #include <WinAPIFiles.au3> #include <Array.au3> Global $bReturnPath = True, $aDateTime[100], $aFiles[100], $aConCat[100] Local $sFilePth = "E:\Clif\Doublestar\", $iHits $aList = _FileListToArray($sFilePth, Default, $FLTA_FOLDERS) If IsArray($aList) Then For $a = 1 To $aList[0] ConsoleWrite("File name is " & $aList[$a] & * .fit & @CRLF) ;this should be a fully qualified file name. If (Not FileFindFirstFile($sFilePth & $aList[$a] & "*.fit" = -1)) Then ConsoleWrite("good hit" & @CRLF) Else ConsoleWrite("skip this file" & @CRLF) EndIf Next EndIfHere are the error messages:"D:\Personal\Dad\AutoIT_Scripts\BoolTest.au3"(13,47) : error: syntax error ConsoleWrite("File name is " & $aList[$a] & * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^"D:\Personal\Dad\AutoIT_Scripts\BoolTest.au3"(13,54) : error: Object method or attribute accessed without 'With'. ConsoleWrite("File name is " & $aList[$a] & * .fit & ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^D:\Personal\Dad\AutoIT_Scripts\BoolTest.au3 - 2 error(s), 0 warning(s)I'm trying to concatenate the path E:\Clif\Doublestar\ with any file in the subdirectory that has the .fit extension *.fitA side issue: Some of the subdirectories contain up to 10.000 files. I want to stop examining files in each subdirectory as soon as I encounter the first .fit file.Thank you for your help.RaySS Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted December 22, 2015 Moderators Share Posted December 22, 2015 RaySS,This looks to work:#include <File.au3> Local $sFilePath = "RootPath\" ; List folders within the root folder $aList = _FileListToArray($sFilePath, Default, $FLTA_FOLDERS) If IsArray($aList) Then For $a = 1 To $aList[0] ConsoleWrite("File pattern: " & $aList[$a] & "\*.fit" & @CRLF) ; List the files matching the wildcard in each folder $aFiles = _FileListToArray($aList[$a], "*.fit", $FLTA_FILES) If IsArray($aFiles) Then ConsoleWrite("Good hit" & @CRLF) ; Take the first such file $sFirstFileFound = $aList[$a] & "\" & $aFiles[1] ; And display it ConsoleWrite("File found: " & $sFirstFileFound & @CRLF) Else ; No files matching the wildcard ConsoleWrite("Skip this folder" & @CRLF) EndIf Next EndIfIt does not stop at the first file - to do that would require you to modify the _FileListToArray function internally - but it seemed pretty fast for me when I tested it.M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
mikell Posted December 22, 2015 Share Posted December 22, 2015 This should work to check the first file found#include <File.au3> Local $sFilePath = "E:\Clif\Doublestar\" $aList = _FileListToArray($sFilePath, Default, $FLTA_FOLDERS, true) If IsArray($aList) Then For $a = 1 To $aList[0] $hSearch = FileFindFirstFile($aList[$a] & "\" & "*.fit") While 1 $sFileName = FileFindNextFile($hSearch) If @error Then ExitLoop ConsoleWrite($aList[$a] & "\" & $sFileName & @CRLF) ExitLoop Wend FileClose($hSearch) Next EndIf Link to comment Share on other sites More sharing options...
ViciousXUSMC Posted December 22, 2015 Share Posted December 22, 2015 (edited) _FileListToArrayRec() should make easy work of this.Here is my shot at it, not sure if faster/better than other solutions already posted, but its easy to understand and use.#Include <File.au3> #Include <Array.au3> Local $sRoot = "C:" Local $sFilter = "*.fit" ;All Files Recurse To Array $aFiles = _FileListToArrayRec($sRoot, $sFilter, $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH) ;Re-Write Array Without File Results Only Directories For $i = 1 to $aFiles[0] $aFiles[$i] = StringRegExpReplace($aFiles[$i], "((.+\\).+)", "$2") Next ;Remove Duplicate Directories Leaving Final Results $aFinal = _ArrayUnique($aFiles, 0, 0, 0, $ARRAYUNIQUE_NOCOUNT) $aFinal[0] = UBound($aFinal) -1 _ArrayDisplay($aFinal)Probably should add a _IsArray() in there for good measure as well to prevent errors if no files exist. This does not meet the "stop on first result" but it does do multi level recursive so if its 10 directories deep it will find it.If its too slow in this form I would modify the _FileListToArrayRec() to show only folders not files and have a all folders filter "*", this will give you every directory listing in a single array with multi level recursive. Then take that arrays results and do a loop with FileFindFirstFile() check using the *.fit filter and if true add it to a new results array.Something like this (Pretty much the merriment of what I have + mikell) combines the concepts. I tried just array delete without arrayuniqe and its terribly slow on a big array or just hung up on something for me.#Include <File.au3> #Include <Array.au3> Local $sRoot = "C:" Local $sFilter = "*.fit" ;All Files Recurse To Array $aFiles = _FileListToArrayRec($sRoot, "*", $FLTAR_FOLDERS, $FLTAR_RECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH) If IsArray($aFiles) Then Local $aFinal[$aFiles[0]] For $i = 1 To $aFiles[0] $hSearch = FileFindFirstFile($aFiles[$i] & "\" & $sFilter) While 1 $sFileName = FileFindNextFile($hSearch) If @error Then ExitLoop $aFinal[$i] = $aFiles[$i] ExitLoop Wend FileClose($hSearch) Next EndIf $aFinal2 = _ArrayUnique($aFinal) For $i2 = UBound($aFinal2) -1 to 0 Step -1 If $aFinal2[$i2] = "" Then _ArrayDelete($aFinal2, $i2) Next $aFinal2[0] = UBound($aFinal2) -1 _ArrayDisplay($aFinal2) Edited December 22, 2015 by ViciousXUSMC Link to comment Share on other sites More sharing options...
RaySS Posted December 23, 2015 Author Share Posted December 23, 2015 Please mark this topic SOLVED.Thanks to m23, mikell, and ViciousXUSMC.I didn't state the problem clearly enough originally.My top directory is named E:\Clif\Doublestar\ It contains a variable number of subdirectories with names like 2015_11_09_022752 BU_385AB The only "good" subdirectories contain at least one file with the .fit extension.Here's the code that is now correctly selecting the good directories:#include <File.au3> Local $sTopDirectory = "E:\Clif\Doublestar\", $sSubdirectoryName, $sMaybeHit ; List folders within the root folder $aList = _FileListToArray($sTopDirectory, Default, $FLTA_FOLDERS) If IsArray($aList) Then For $a = 1 To $aList[0] $sSubdirectoryName = $sTopDirectory & $aList[$a] ConsoleWrite("Subdirectory Name: " & $sSubdirectoryName & @CRLF) ConsoleWrite("File pattern: " & $sSubdirectoryName & "\*.fit" & @CRLF) $sMaybeHit = "0" $hSearch = FileFindFirstFile($sSubdirectoryName & "\" & "*.fit") While 1 $sFileName = FileFindNextFile($hSearch) If @error Then ExitLoop $sMaybeHit = $aList[$a] & "\" & $sFileName ConsoleWrite($aList[$a] & "\" & $sFileName & @CRLF) ExitLoop WEnd FileClose($hSearch) If Not ($sMaybeHit = "0") Then ConsoleWrite("Good hit" & @CRLF) Else ; No files matching the wildcard ConsoleWrite("Skip this folder" & @CRLF) EndIf Next EndIfHere's sample output:Subdirectory Name: E:\Clif\Doublestar\2015_11_09_022752 BU_385ABFile pattern: E:\Clif\Doublestar\2015_11_09_022752 BU_385AB\*.fitSkip this folderSubdirectory Name: E:\Clif\Doublestar\2015_11_09_022752 BU_bogus1File pattern: E:\Clif\Doublestar\2015_11_09_022752 BU_bogus1\*.fit2015_11_09_022752 BU_bogus1\doublestar_2015_11_09_022752_1000.fitGood hitSubdirectory Name: E:\Clif\Doublestar\2015_11_09_022752 BU_bogus2File pattern: E:\Clif\Doublestar\2015_11_09_022752 BU_bogus2\*.fitSkip this folderSubdirectory Name: E:\Clif\Doublestar\2015_11_09_023228 SAO73075File pattern: E:\Clif\Doublestar\2015_11_09_023228 SAO73075\*.fit2015_11_09_023228 SAO73075\doublestar_2015_11_09_023228_0000(2).fitGood hitSubdirectory Name: E:\Clif\Doublestar\2015_11_09_023228 SAObogus1File pattern: E:\Clif\Doublestar\2015_11_09_023228 SAObogus1\*.fit2015_11_09_023228 SAObogus1\doublestar_2015_11_09_023228_1983.fitGood hitI can confirm that the script did find the three good subdirectories, and it skipped the two that do not contain any .fit files.Again thank you!RaySS Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now