LurchMan Posted July 12, 2010 Share Posted July 12, 2010 Hey everyone - I'm working on a script that in one portion of it, it is suppose to list all files in a directory matching a specified search string and put it into an array. The problem I'm having is that the files are named like such: 07.05.2010_random From what I've read using FileFindFirstFile () I can only use one wildcard on each side of a period (I tried and it didn't work using the wildcards with the search string). The code below I'm using _FileListToArray () but that appears to have the same problem. Anyone got an suggestions on how I can go about this....Listing all files and looping through the array will take forever due to the amount of files that this will be looking through..Any help is appreciated Code: Func _FindFiles($sFrom, $sTo) ;requires 2 dates in the format of YYYY/MM/DD $sPath = "C:\ppgtest" ;Debug use only $iBot = StringRight($sFrom, 2) $iTop = StringRight($sTo, 2) $iMon = StringMid($sFrom, 6, 2) $iYear = StringLeft($sFrom, 4) Local $aFiles[1] If $iMon <> StringMid($sTo, 6, 2) Then $rtn = MsgBox(36, "Different Months", "You have selected to zip files across 2 different months..Are you sure you wish to continue?") If $rtn = 7 Then GUISetState(@SW_SHOW) Return EndIf EndIf For $n = $iBot To $iTop $aTemp = _FileListToArray ($sPath,$iMon & "." & $n & "." & $iYear & "*", 1) If Not @error Then _ArrayConcatenate ($aFiles, $aTemp, 1) Else Select Case @error = 1 MsgBox (16, "Error", "Error: Invalid Search Path.") GUISetState(@SW_SHOW) Return Case @error = 4 MsgBox (16, "Error", "Error: No files found for specified dates.") GUISetState(@SW_SHOW) Return EndSelect EndIf Next _ArrayDisplay($aFiles) ;Debug use only Return $aFiles EndFunc ;==>_FindFiles Dating a girl is just like writing software. Everything's going to work just fine in the testing lab (dating), but as soon as you have contract with a customer (marriage), then your program (life) is going to be facing new situations you never expected. You'll be forced to patch the code (admit you're wrong) and then the code (wife) will just end up all bloated and unmaintainable in the end. Link to comment Share on other sites More sharing options...
Spiff59 Posted July 12, 2010 Share Posted July 12, 2010 (edited) Hey everyone - I'm working on a script that in one portion of it, it is suppose to list all files in a directory matching a specified search string and put it into an array. The problem I'm having is that the files are named like such: 07.05.2010_random From what I've read using FileFindFirstFile () I can only use one wildcard on each side of a period (I tried and it didn't work using the wildcards with the search string). The code below I'm using _FileListToArray () but that appears to have the same problem. Anyone got an suggestions on how I can go about this....Listing all files and looping through the array will take forever due to the amount of files that this will be looking through..Any help is appreciated _FileListToArray() ought to work with those search parameters. I do see you need to append a leading zero in some cases to your search string: $sSearch = $iMon & "." & Stringright( "0" & $n, 2) & "." & $iYear & "*" $aTemp = _FileListToArrayZ ($sPath, $sSearch, 1) And since you'll surely have days in the search period with no files, you need to comment out this: Case @error = 4 MsgBox (16, "Error", "Error: No files found for specified dates.") GUISetState(@SW_SHOW) Return Beyond that, it ought to work. Edit: PS - If this is a new project you're working on, one where you have some choice in naming your input files, I'd keep them in a yyyy/mm/dd format, like "2010.07.20_random" as they'll then list/display chronologically. And... the docs are incorrect, you can get more creative with the wildcard strings than they imply. If you used one of the other versions of _FileListToArray that are around that allow multiple filters, they'll just internally be executing the routine multiple times same as when you're controlling the loop externally. The only thing I could think of to reduce your i/o would be a logic routine up front to try and boil your date range down to the least number of searches, one that might turn a date range of say, 2010.07.01 through 2010.07.22 into four search strings: "07.0?.2010*", "07.1?.2010*", "07.21.2010*", and "07.22.2010*". Edited July 12, 2010 by Spiff59 Link to comment Share on other sites More sharing options...
LurchMan Posted July 12, 2010 Author Share Posted July 12, 2010 _FileListToArray() ought to work with those search parameters. I do see you need to append a leading zero in some cases to your search string: $sSearch = $iMon & "." & Stringright( "0" & $n, 2) & "." & $iYear & "*" $aTemp = _FileListToArrayZ ($sPath, $sSearch, 1) And since you'll surely have days in the search period with no files, you need to comment out this: Case @error = 4 MsgBox (16, "Error", "Error: No files found for specified dates.") GUISetState(@SW_SHOW) Return Beyond that, it ought to work. Edit: PS - If this is a new project you're working on, one where you have some choice in naming your input files, I'd keep them in a yyyy/mm/dd format, like "2010.07.20_random" as they'll then list/display chronologically. Thank you for the reply..the leading zero will be there - before the date gets to the function I do a StringFormat on it and do zero padding on the month and day of the date. I tried your suggestion: $sSearch = $iMon & "." & Stringright( "0" & $n, 2) & "." & $iYear & "*" $aTemp = _FileListToArray ($sPath,$sSearch, 1) And this works for some reason....Dare I ask why this works even when I do a zero padding on it before it gets there? Thank you for the tip on the error code, and I wish this was a new project..but I have no control over the file name. Dating a girl is just like writing software. Everything's going to work just fine in the testing lab (dating), but as soon as you have contract with a customer (marriage), then your program (life) is going to be facing new situations you never expected. You'll be forced to patch the code (admit you're wrong) and then the code (wife) will just end up all bloated and unmaintainable in the end. Link to comment Share on other sites More sharing options...
Spiff59 Posted July 12, 2010 Share Posted July 12, 2010 Dare I ask why this works even when I do a zero padding on it before it gets there?You're zero-padding your $iTop/$iBot variables?Or... you're padding the $n variable that is used to construct the search string??? Link to comment Share on other sites More sharing options...
LurchMan Posted July 12, 2010 Author Share Posted July 12, 2010 You're zero-padding your $iTop/$iBot variables?Or... you're padding the $n variable that is used to construct the search string???I see my error now...the zero padding won't stay when I start adding to it..correct? Dating a girl is just like writing software. Everything's going to work just fine in the testing lab (dating), but as soon as you have contract with a customer (marriage), then your program (life) is going to be facing new situations you never expected. You'll be forced to patch the code (admit you're wrong) and then the code (wife) will just end up all bloated and unmaintainable in the end. Link to comment Share on other sites More sharing options...
Spiff59 Posted July 12, 2010 Share Posted July 12, 2010 (edited) I see my error now...the zero padding won't stay when I start adding to it..correct?I'm sure the $n variable, generated as the counter in your for/next loop, does not inherit any formatting that exists in the variables used to set it's start and end values, and would need to be manually formatted for each iteration of the loop. Edited July 12, 2010 by Spiff59 Link to comment Share on other sites More sharing options...
LurchMan Posted July 12, 2010 Author Share Posted July 12, 2010 I'm sure the $n variable, generated as the counter in your for/next loop, does not inherit any formatting that exists in the variables used to set it's start and end values, and would need to be manually formatted for each iteration of the loop.Yup..I see that now..thanks for the help everyone. Dating a girl is just like writing software. Everything's going to work just fine in the testing lab (dating), but as soon as you have contract with a customer (marriage), then your program (life) is going to be facing new situations you never expected. You'll be forced to patch the code (admit you're wrong) and then the code (wife) will just end up all bloated and unmaintainable in the end. Link to comment Share on other sites More sharing options...
Spiff59 Posted July 13, 2010 Share Posted July 13, 2010 (edited) Yup..I see that now..thanks for the help everyone. I got bored... This is what I came up with to accept a date range, and refine it into the least number of search filters to feed into _FileListToArray() to nail your files. Was a fun way to spend an hour (edit2: or two!) expandcollapse popup#include <Array.au3> ; Not required by function #include <Date.au3> Global $StartDate = "2008/12/12", $EndDate = "2010/03/25" MsgBox(1,"", "Days in range (inclusive) = " & _DateDiff("d", $StartDate, $EndDate) + 1) $aFilter_Array = _Date_Range_Filters($StartDate, $EndDate) $aFilter_Array = _Date_Range_Filters($StartDate, $EndDate, "YYYYMMDD") $aFilter_Array = _Date_Range_Filters($StartDate, $EndDate, "MM.DD.YYYY") _ArrayDisplay($aFilter_Array) ;For $x = 1 to $aFilter_Array[0] ; _FileListToArray($sPath, $aFilter_Array[$x] & "_*", 1) ;Next Exit ; #FUNCTION# ==================================================================================================================== ; Name...........: _Date_Range_Filters ; Description ...: Accept a YYYY/MM/DD date range and compress into an array of DOS search filters ; Syntax.........: _Date_Range_Filters($sStart, $sEnd [, $sFormat]) ; Parameters ....: $sStart - Start of date range (YYYY/MM/DD) ; $sEnd - End of date range (YYYY/MM/DD) ; $sFormat - Returned date format. "YYYY", "MM" and "DD" in any order, any or no delimiter. Default = "YYYY-MM-DD" ; Return values .: Success - Returns a 1-dimension 1-based array containing DOS search filters ; Author ........: Spiff59 ; =============================================================================================================================== Func _Date_Range_Filters($sStart, $sEnd, $sFormat = "YYYY-MM-DD") Local $sArray, $iFirstMonth, $iLastMonth, $iFirstDay, $iLastDay, $sDay, $sMon Local $aStart = StringSplit($sStart, "/") Local $aEnd = StringSplit($sEnd, "/") ; Process $sFormat string Local $sDelim = " & '" & StringLeft(StringRegExpReplace($sFormat, "[YyMmDd]", ""), 1) & "' & " $sFormat = StringSplit(StringRegExpReplace(StringRegExpReplace($sFormat, "[^YyMmDd]", ""), "(.)(\1)+", "$1"),"") For $x = 1 to 3 If $sFormat[$x] = "Y" Then $sFormat[$x] = "$y" If $sFormat[$x] = "M" Then $sFormat[$x] = "$sMon" If $sFormat[$x] = "D" Then $sFormat[$x] = "$sDay" Next $sFormat = $sFormat[1] & $sDelim & $sFormat[2] & $sDelim & $sFormat[3] ; Build array For $y = $aStart[1] to $aEnd[1] ; year loop If $y = $aStart[1] Then $iFirstMonth = $aStart[2] Else $iFirstMonth = 1 EndIf If $y = $aEnd[1] Then $iLastMonth = $aEnd[2] Else $iLastMonth = 12 EndIf For $m = $iFirstMonth to $iLastMonth ; month loop $iMaxDays = _DateDaysInMonth($y, $m) If $y = $aStart[1] And $m = $aStart[2] Then $iFirstDay = $aStart[3] Else $iFirstDay = 1 EndIf If $y = $aEnd[1] And $m = $aEnd[2] Then $iLastDay = $aEnd[3] Else $iLastDay = $iMaxDays EndIf For $d = $iFirstDay to $iLastDay ; day loop If $y > $aStart[1] And $y < $aEnd[1] Then $sMon = "??" $m = $iLastMonth $sDay = "??" $d = $iMaxDays Else $sMon = $m $sMon = Stringright( "0" & $m, 2) Select Case $d = 1 And $iLastDay = $iMaxDays $sDay = "??" $d = $iMaxDays Case $d = 1 And $iLastDay > 8 $sDay = "0?" $d += 8 Case Not Mod($d, 10) And ($iLastDay > ($d + 8) Or $iLastDay = $iMaxDays) $sDay = Int($d / 10) & "?" $d += 9 Case Else $sDay = Stringright( "0" & $d, 2) EndSelect Endif $sArray &= Execute($sFormat) & "|" Next Next Next Return StringSplit(StringTrimRight($sArray, 1), "|") EndFunc Edit: Added _DateDiff statement to show compression ratio. In this example, 469 days are crunched into 21 search filters. Edit2: Added format parameter and function header Edit3: Allow input date range to span multiple years Edited July 21, 2010 by Spiff59 Link to comment Share on other sites More sharing options...
LurchMan Posted July 13, 2010 Author Share Posted July 13, 2010 Wow...thank you lol Dating a girl is just like writing software. Everything's going to work just fine in the testing lab (dating), but as soon as you have contract with a customer (marriage), then your program (life) is going to be facing new situations you never expected. You'll be forced to patch the code (admit you're wrong) and then the code (wife) will just end up all bloated and unmaintainable in the end. Link to comment Share on other sites More sharing options...
Spiff59 Posted July 13, 2010 Share Posted July 13, 2010 I changed it (post #8) again! I made it so you can specify any delimiter in the return dates, OR, no delimiter. I'm kinda fond of the ease/flexibility of the $sFormat variable I do think I'm finished with the routine now. I didn't do this entirely for altruistic reasons, I have some directories myself where the filenames contain dates. I can stick whatever filename prefix and/or suffix onto each of the elements returned from the array and use them to find all filenames dated within a certain time period. I have many files that contain "YYYYMMDD" in the filemane, and some that have "MM-DD-YYYY" within the filename. I should be able to use this on any of them. 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