Blitzkid Posted September 26, 2019 Posted September 26, 2019 (edited) Hello, i want to search several directories for files with the largest numbers behind them (Like "video123") . They dont have a datatype. But there are also files with longer names and datatypes in these folders (Like "video778.mp4"). Is it possible to filter the _FileListToArray Syntax from Quote _FileListToArray($filedir & $arr[$i], $arr[$i] & "*", 1) to smth. like Quote _FileListToArray($filedir & $arr[$i], $arr[$i] & " 3 Numbers", 1) Here is my Code #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <array.au3> #include <File.au3> $filedir = @ScriptDir & "\" _checkfile() Func _checkfile() ConsoleWrite("______________________" & @CRLF) Local $arr[3] = ["music", "picture", "video"] For $i = 0 To UBound($arr) - 1 Local $arrayfiles = _FileListToArray($filedir & $arr[$i], $arr[$i] & "*", 1) If @error = 1 Then ConsoleWrite($arr[$i] & "Error 1") EndIf If @error = 4 Then ConsoleWrite($arr[$i] & "Error 2") ;Exit EndIf $arrayfilter = _ArrayMax($arrayfiles, 0, 1) Global $stringfiles = StringReplace($arrayfilter, $arr[$i], "") ConsoleWrite($arrayfilter & @CRLF) Next EndFunc ;==>_checkfile Edited September 26, 2019 by Blitzkid
seadoggie01 Posted September 26, 2019 Posted September 26, 2019 Yes, you'll just need to loop through your array to strip out the music/picture/video text before getting the max... ; Strip out the current file prefix For $f = 0 To UBound($arrayFiles) - 1 $arrayFiles[$f] = StringReplace($arrayFiles[$f], $arr[$i], "") Next ; Get the max $arrayfilter = _ArrayMax($arrayFiles, 0, 1) ; Put the prefix back $arrayfilter = $arr[$i] & $arrayfilter All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types
Blitzkid Posted September 26, 2019 Author Posted September 26, 2019 1 hour ago, seadoggie01 said: Yes, you'll just need to loop through your array to strip out the music/picture/video text before getting the max... ; Strip out the current file prefix For $f = 0 To UBound($arrayFiles) - 1 $arrayFiles[$f] = StringReplace($arrayFiles[$f], $arr[$i], "") Next ; Get the max $arrayfilter = _ArrayMax($arrayFiles, 0, 1) ; Put the prefix back $arrayfilter = $arr[$i] & $arrayfilter Thx for the fast reply, but my problem is that i only need the files with the name f.e. video544 (always 3 numbers behind it). There are also files like video737.mp4 included. But i dont need them, but when i search for the maxnumber i'll always get the one with .mp4 in the end, instead of f.e. video544.... I need a solution that replace the "*" filter in _FileListToArray to something like "3 numbers"...
ajag Posted September 26, 2019 Posted September 26, 2019 (edited) > I need a solution that replace the "*" filter in _FileListToArray to something like "3 numbers"... Maybe "???" instead of "*". I think this will work. Not exactly what you want, but closer ("videoABC" will also be found) Ajag Edited September 26, 2019 by ajag Rule #1: Always do a backup Rule #2: Always do a backup (backup of rule #1)
Blitzkid Posted September 26, 2019 Author Posted September 26, 2019 2 minutes ago, ajag said: > I need a solution that replace the "*" filter in _FileListToArray to something like "3 numbers"... Maybe "???" instead of "*". I think this will work. Not exactly what you want, but closer ("videoABC" will also be found) Ajag Yes ??? is a option, but it includes letters aswell, is there a filter that includes only numbers?
seadoggie01 Posted September 26, 2019 Posted September 26, 2019 (edited) To ignore non-numbers, just wrap it in Number(), it returns 0 when the value isn't a number, so it will never be the max ; Strip out the current file prefix For $f = 0 To UBound($arrayFiles) - 1 $arrayFiles[$f] = Number(StringReplace($arrayFiles[$f], $arr[$i], "")) Next ; Get the max $arrayfilter = _ArrayMax($arrayFiles, 1, 1) ; Put the prefix back $arrayfilter = $arr[$i] & $arrayfilter Edited September 26, 2019 by seadoggie01 ArrayMax should get largest integer, not character All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types
Blitzkid Posted September 26, 2019 Author Posted September 26, 2019 2 minutes ago, seadoggie01 said: To ignore non-numbers, just wrap it in Number(), it returns 0 when the value isn't a number, so it will never be the max ; Strip out the current file prefix For $f = 0 To UBound($arrayFiles) - 1 $arrayFiles[$f] = Number(StringReplace($arrayFiles[$f], $arr[$i], "")) Next ; Get the max $arrayfilter = _ArrayMax($arrayFiles, 0, 1) ; Put the prefix back $arrayfilter = $arr[$i] & $arrayfilter This sounds good, i'll test it out tomorrow and update this post
Musashi Posted September 26, 2019 Posted September 26, 2019 (edited) 16 hours ago, Blitzkid said: I need a solution that replace the "*" filter in _FileListToArray to something like "3 numbers"... It is, as far as I know, not possible to use a regular expression as a filter in _FileListToArray(Rec). Here is a variation with FileFindFirstFile and FileFindNextFile (will also match video001). I moved the array from the function to the global scope too. In the attachment you will find a Zip with test files (dummies only). Like in your script the subfolders \music , \picture and \video are used. #include <File.au3> Global $g_sFileDir Global $g_aArr[3] = ["music", "picture", "video"] For $i = 0 To UBound($g_aArr) - 1 $g_sFileDir = @ScriptDir & "\" & $g_aArr[$i] & "\" ConsoleWrite("< "& $g_aArr[$i] & " -> highest number = " & _GetFileHighNum($g_sFileDir, $g_aArr[$i]) & @CRLF) Next ; --------------------------------------------------------------------- Func _GetFileHighNum($sFileDir, $sSearchName) Local $hSearch, $sCurrentFile, $iMaxNum = 0, $iNum = 0 $hSearch = FileFindFirstFile($sFileDir & $sSearchName & '*') If $hSearch = -1 Then Return 0 While 1 $sCurrentFile = FileFindNextFile($hSearch) If @error Then FileClose($hSearch) Return $iMaxNum EndIf If StringRegExp($sCurrentFile, '(?i)^' & $sSearchName & '\d{3}$') Then $iNum = Number(StringRegExpReplace($sCurrentFile, '\D', '')) If (Not @error) And ($iNum >= $iMaxNum) Then $iMaxNum = $iNum EndIf WEnd EndFunc ;==>_GetFileHighNum TestFolders.zip Edited September 27, 2019 by Musashi moved FileClose($hSearch) to if @error FrancescoDiMuro and Blitzkid 2 "In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."
Blitzkid Posted September 27, 2019 Author Posted September 27, 2019 (edited) 8 hours ago, Musashi said: It is, as far as I know, not possible to use a regular expression as a filter in _FileListToArray(Rec). Here is a variation with FileFindFirstFile and FileFindNextFile (will also match video001). I moved the array from the function to the global scope too. In the attachment you will find a Zip with test files (dummies only). Like in your script the subfolders \music , \picture and \video are used. #include <File.au3> Global $g_sFileDir Global $g_aArr[3] = ["music", "picture", "video"] For $i = 0 To UBound($g_aArr) - 1 $g_sFileDir = @ScriptDir & "\" & $g_aArr[$i] & "\" ConsoleWrite("< "& $g_aArr[$i] & " -> highest number = " & _GetFileHighNum($g_sFileDir, $g_aArr[$i]) & @CRLF) Next ; --------------------------------------------------------------------- Func _GetFileHighNum($sFileDir, $sSearchName) Local $hSearch, $sCurrentFile, $iMaxNum = 0, $iNum = 0 $hSearch = FileFindFirstFile($sFileDir & $sSearchName & '*') If $hSearch = -1 Then Return 0 While 1 $sCurrentFile = FileFindNextFile($hSearch) If @error Then Return $iMaxNum If StringRegExp($sCurrentFile, '(?i)^' & $sSearchName & '\d{3}$') Then $iNum = Number(StringRegExpReplace($sCurrentFile, '\D', '')) If (Not @error) And ($iNum >= $iMaxNum) Then $iMaxNum = $iNum EndIf WEnd FileClose($hSearch) EndFunc ;==>_GetFileHighNum TestFolders.zip 3.19 kB · 0 downloads Thats exactly what i needed, thank you very much ♥ Also big thank you to @seadoggie01 and @ajag Edited September 27, 2019 by Blitzkid
Musashi Posted September 27, 2019 Posted September 27, 2019 5 minutes ago, Blitzkid said: Thats exactly what i needed, thank you very much ♥ You are welcome 🙂. I have made one minor change : FileClose($hSearch) was moved from the end of the function behind if @error... (view my code sample above), because I leave the while loop with Return, not with ExitLoop. "In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."
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