Jump to content

Filter for _FileListToArray


Blitzkid
 Share

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 comment
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
InputBoxes - Simple Input boxes for various variable types

Link to comment
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 comment
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 comment
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 comment
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
InputBoxes - Simple Input boxes for various variable types

Link to comment
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 comment
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 comment
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 comment
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 comment
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
 Share

×
×
  • Create New...