Jump to content

Recommended Posts

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 by Blitzkid
Link to post
Share on other sites

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 functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager

Link to post
Share on other sites
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"...

Link to post
Share on other sites

> 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 by ajag

Rule #1: Always do a backup         Rule #2: Always do a backup (backup of rule #1)

Link to post
Share on other sites
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?

Link to post
Share on other sites

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 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 functions
Acro.au3 UDF - Automating Acrobat Pro
ToDo Finder - Find #ToDo: lines in your scripts
UI-SimpleWrappers UDF - Use UI Automation more Simply-er
KeePass UDF - Automate KeePass, a password manager

Link to post
Share on other sites
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 :)

Link to post
Share on other sites
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 by Musashi
moved FileClose($hSearch) to if @error

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to post
Share on other sites
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 by Blitzkid
Link to post
Share on other sites
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.

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By mLipok
      Usually when I collect data from DataBase I need to give EndUser a possibility to select rows which should be taken in the processing loop.
      I was searching on the forum and I'm not able to find any UDF or even example of how to select data from array.
      I have my own solutions but I think they are not worth posting on the forum as it is very old code and I am looking for a better solution.

      Could anybody point me to some examples/solutions ?

      Thank you in advance.
      @mLipok
    • By EmilyLove
      I have a string containing the full path of an executable and an array of executables without their paths. I am trying to compare the string to the list in the array and if a match is found, remove it from the array. The entry get removed from the array successfully, and after checking its return result, uses it to update the ubound if it succeeded, but it doesn't want to update to the new value. Any ideas what I am doing wrong? It acts like it is read-only.
      #include <Array.au3> #include <File.au3> Local $sApp_Exe = "F:\App\Nextcloud\nextcloud.exe" Local $aWaitForEXEX = [3, "Nextcloud.exe", "nextcloudcmd.exe", "QtWebEngineProcess.exe"] For $h = 1 To $aWaitForEXEX[0] If StringInStr($sApp_Exe, $aWaitForEXEX[$h]) <> 0 Then $iRet = _ArrayDelete($aWaitForEXEX, $h) If $iRet <> -1 Then $aWaitForEXEX[0] = $iRet ;this line doesn't work. $aWaitForEXEX[0] doesn't update and shortly gives Error: Array variable has incorrect number of subscripts or subscript dimension range exceeded.: _ArrayDisplay($aWaitForEXEX) EndIf Next  
    • By vinnyMS
      #Include <Array.au3> #include <Constants.au3> $s = FileRead("2.txt") Local $w = StringRegExp($s, '(?is)(\b\w+\b)(?!.*\b\1\b)', 3) _ArrayColInsert($w, 1) For $i = 0 to UBound($w)-1 StringRegExpReplace($s, '(?i)\b' & $w[$i][0] & '\b', $w[$i][0]) $w[$i][1] = @extended Next _ArraySort($w, 1, 0, 0, 1) _ArrayDisplay($w) i have this script that returns 3 columns  
       
      i need to copy the  Col 0 and Col 1 as text to paste on notepad or excel
      you will have to create a "copy" button if possible
      array.au3 2.txt
    • By DannyJ
      I have a dataset like this, (a strubg)
      Username: User1 Type: Admin RegDate: 1999 Username: User2 Type: User RegDate: 2000 How to make a 2 dimensional array that I can display with _ArrayDisplay?
      This would be a perfect 2D array to represent my data:
      Username           Tpye RegDate User1              Admin 1999 User2              User 2000   If you run this Powershell this powershell command, you can get this dataset that I am talking about:
      Get-LocalUser | Select * With this code you can try it to read into a string:
      #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #include "GUIListViewEx.au3" #include <Array.au3> ; Just for display in example #RequireAdmin #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #EndRegion $sCommand = "powershell.exe Get-LocalUser | Select *" Local $iPid = Run($sCommand, @WorkingDir , @SW_SHOW , $STDOUT_CHILD) ProcessWaitClose($iPid) Local $sOutput = StdoutRead($iPID) ConsoleWrite($sOutput) How can I correctly split $sOutput into a 2D array (with the above mentioned layout) that I can display and I work with?
    • By kovlad
      My solution is to write nested arrays without copying.
      The problem was described hier.
       
      Function:
      #include <Array.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _ArrayNestedSet ; Description ...: Assigns a value to an element of a nested 1D array. ; Syntax ........: _ArrayNestedSet(ByRef $aArray, $vIndex, $vValue) ; Parameters ....: $aArray - an array of arrays. ; $vIndex - an index or 1d-array of indexes; ; a size if $vValue not defined (zero to delete). ; $vValue - a value (create, resize or delete if not defined). ; ; Return values .: on success - 1 ; @extended - nesting level of operation ; on failure - 0 ; @extended - nesting level of error ; @error = 1 - invalid array ; @error = 2 - invalid index ; Author ........: ; Modified ......: kovlad ; Remarks .......: ; Related .......: ; Link ..........: https://www.autoitscript.com/forum/topic/185638-assign-a-value-to-an-array-in-array-element/ ; https://www.autoitscript.com/trac/autoit/ticket/3515?replyto=description ; Example .......: Yes ; =============================================================================================================================== Func _ArrayNestedSet(ByRef $aArray, $vIndex, $vValue = Default) Local $extended = @extended + 1 If IsArray($vIndex) Then If UBound($vIndex, 0) <> 1 Then _ Return SetError(2, $extended) If UBound($vIndex) > 1 Then If UBound($aArray, 0) <> 1 Then _ Return SetError(1, $extended) ; keep index for this array Local $i = $vIndex[0] If $i < 0 Or UBound($aArray) <= $i Then _ Return SetError(2, $extended) ; delete index of this array _ArrayDelete($vIndex, 0) ; recursive function call Local $return = _ArrayNestedSet($aArray[$i], $vIndex, $vValue) If @error Then Return SetError(@error, @extended + 1, 0) Else Return SetExtended(@extended + 1, 1) EndIf Else $vIndex = $vIndex[0] EndIf EndIf If $vValue = Default Then If $vIndex < 0 Then _ Return SetError(2, $extended) If $vIndex = 0 Then ; delete array and free memory $aArray = 0 Return SetExtended($extended, 1) EndIf If UBound($aArray, 0) = 1 Then ; resize array keeping data ReDim $aArray[$vIndex] Return SetExtended($extended, 1) Else ; create new nested array Local $aTmp[$vIndex] $aArray = $aTmp Return SetExtended($extended, 1) EndIf Else If UBound($aArray) <= $vIndex Then _ Return SetError(2, $extended + 1) ; set value of array entry $aArray[$vIndex] = $vValue Return SetExtended($extended, 1) EndIf EndFunc  
      Examples:
      ; write value to 1st nested array ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : write value to 1st nested array" & @CRLF) Local $aTmp1[4] = [1,2,3,4] _ArrayDisplay($aTmp1, "$aTmp1") Local $aArray[2] = [$aTmp1] ConsoleWrite( _ "_ArrayNestedSet($aArray[0], 3, 14) = " & _ArrayNestedSet($aArray[0], 3, 14) & @CRLF & _ " @error = " & @error & @CRLF & _ " @extended = " & @extended & @CRLF & @CRLF) _ArrayDisplay($aArray[0], "$aArray[0]") ; resize 1st nested array ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : resize 1st nested array" & @CRLF) ConsoleWrite( _ "_ArrayNestedSet($aArray[0], 8) = " & _ArrayNestedSet($aArray[0], 8) & @CRLF & _ " @error = " & @error & @CRLF & _ " @extended = " & @extended & @CRLF & @CRLF) _ArrayDisplay($aArray[0], "$aArray[0]") ; write array to 1st nested array ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : write array to 1st nested array" & @CRLF) Local $aTmp11[4] = [11,12,13,14] _ArrayDisplay($aTmp11, "$aTmp11") ConsoleWrite( _ "_ArrayNestedSet($aArray[0], 2, $aTmp11) = " & _ArrayNestedSet($aArray[0], 2, $aTmp11) & @CRLF & _ " @error = " & @error & @CRLF & _ " @extended = " & @extended & @CRLF & @CRLF) _ArrayDisplay(($aArray[0])[2], "($aArray[0])[2]") ; write value to 2nd nested array using index array ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : write value to 2nd nested array using index array" & @CRLF) Local $aIndex1[2] = [2,3] _ArrayDisplay($aIndex1, "$aIndex1") ConsoleWrite( _ "_ArrayNestedSet($aArray[0], $aIndex1, 140) = " & _ArrayNestedSet($aArray[0], $aIndex1, 140) & @CRLF & _ " @error = " & @error & @CRLF & _ " @extended = " & @extended & @CRLF & @CRLF) _ArrayDisplay(($aArray[0])[2], "($aArray[0])[2]") ; resize 2nd nested array ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : resize 2nd nested array" & @CRLF) Local $aIndex1[2] = [2,8] _ArrayDisplay($aIndex1, "$aIndex1") ConsoleWrite( _ "_ArrayNestedSet($aArray[0], $aIndex1) = " & _ArrayNestedSet($aArray[0], $aIndex1) & @CRLF & _ " @error = " & @error & @CRLF & _ " @extended = " & @extended & @CRLF & @CRLF) _ArrayDisplay(($aArray[0])[2], "($aArray[0])[2]") ; create new 3rd nested array ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : create new 3rd nested array" & @CRLF) Local $aIndex2[3] = [2,7,6] _ArrayDisplay($aIndex2, "$aIndex2") ConsoleWrite( _ "_ArrayNestedSet($aArray[0], $aIndex2) = " & _ArrayNestedSet($aArray[0], $aIndex2) & @CRLF & _ " @error = " & @error & @CRLF & _ " @extended = " & @extended & @CRLF & @CRLF) _ArrayDisplay((($aArray[0])[2])[7], ")($aArray[0])[2])[7]") ; delete 3rd nested array ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : delete 3rd nested array" & @CRLF) Local $aIndex3[3] = [2,7,0] _ArrayDisplay($aIndex3, "$aIndex2") ConsoleWrite( _ "_ArrayNestedSet($aArray[0], $aIndex3) = " & _ArrayNestedSet($aArray[0], $aIndex3) & @CRLF & _ " @error = " & @error & @CRLF & _ " @extended = " & @extended & @CRLF) ConsoleWrite("IsArray((($aArray[0])[2])[7]) = " & IsArray((($aArray[0])[2])[7]) & @CRLF & @CRLF) ; write 0 in 1st nested array to delete the 2nd nested array ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : write 0 in 1st nested array to delete the 2nd nested array" & @CRLF) Local $aIndex4[1] = [2] _ArrayDisplay($aIndex4, "$aIndex4") ConsoleWrite( _ "_ArrayNestedSet($aArray[0], $aIndex4, 0) = " & _ArrayNestedSet($aArray[0], $aIndex4, 0) & @CRLF & _ " @error = " & @error & @CRLF & _ " @extended = " & @extended & @CRLF) ConsoleWrite("IsArray(($aArray[0])[2]) = " & IsArray(($aArray[0])[2]) & @CRLF & @CRLF) ; delete 1st nested array (same as '$aArray[0] = 0') ConsoleWrite("@@ Debug(" & @ScriptLineNumber & ") : delete 1st nested array (same as '$aArray[0] = 0')" & @CRLF) Local $aIndex5[1] = [0] _ArrayDisplay($aIndex5, "$aIndex5") ConsoleWrite( _ "_ArrayNestedSet($aArray[0], $aIndex5) = " & _ArrayNestedSet($aArray[0], $aIndex5) & @CRLF & _ " @error = " & @error & @CRLF & _ " @extended = " & @extended & @CRLF) ConsoleWrite("IsArray($aArray[0]) = " & IsArray($aArray[0]) & @CRLF & @CRLF)  
×
×
  • Create New...