Jump to content
VIP

[Solved] Help sort the directory tree under the level. _FileListToArrayRec()

Recommended Posts

Please help me sort the directory tree by level.
I want to sort the folders in order: 6-> 5> 4> 3> 2> 1

Thanks for all the help and suggestions!

computer-network-file-folder-organization-structure-flowchart-vector-graphic-sharp-professional-tree-concept-traditional-yellow-106778812.thumb.jpg.72de129fd00585f89adde06bf0b3db21.jpg

#include <File.au3>
#include <Array.au3>

Global Const $sRemotePath = '/user/trong/sync'
Global Const $sLocalPath = @MyDocumentsDir

_Sequential($sLocalPath, $sRemotePath)

Func _Sequential($iLocalPath, $iRemotePath)
    $iLocalPath = StringReplace($iLocalPath, "/", "\")
    $iRemotePath = StringReplace($iRemotePath, "\", "/")
    If (StringRight($iLocalPath, 1) = "\") Then $iLocalPath = StringTrimRight($iLocalPath, 1)
    ConsoleWrite("> From: " & $iLocalPath & @CRLF)
    ConsoleWrite(">   TO: " & $iRemotePath & @CRLF)
    Local $aDirList = _FileListToArrayRec($iLocalPath, '*', $FLTAR_FOLDERS, $FLTAR_RECUR, $FLTAR_SORT, $FLTAR_FULLPATH)
    If (Not @error) And IsArray($aDirList) Then
        For $d = 1 To $aDirList[0]
            ConsoleWrite("! Current Path (" & $d & '/' & $aDirList[0] & '): ' & $aDirList[$d] & @CRLF)
            Local $aFileList = _FileListToArray($aDirList[$d], '*', $FLTA_FILES, False)
            If (Not @error) And IsArray($aFileList) Then
                For $f = 1 To $aFileList[0]
                    ConsoleWrite("+ File: (" & $f & '/' & $aFileList[0] & ') ON Path ' & $d & '/' & $aDirList[0] & @CRLF)
                    Local $iPathName = StringReplace($aDirList[$d], $iLocalPath & '\', '')
                    Local $iFileName = _SplitPath($aFileList[$f], 5)
                    Local $iRemoteDir = StringReplace($iRemotePath & '/' & $iPathName, '\', '/')
                    Local $iRemoteFile = StringReplace($iRemoteDir & '/' & $iFileName, '\', '/')
                    Local $iLocalFile = $aDirList[$d] & '\' & $iFileName

                    ConsoleWrite("- Path Name  : " & $iPathName & @CRLF)
                    ConsoleWrite("- File Name  : " & $iFileName & @CRLF)
                    ConsoleWrite("- Remote Dir : " & $iRemoteDir & @CRLF)
                    ConsoleWrite("- Remote File: " & $iRemoteFile & @CRLF)
                    ConsoleWrite("- Local File : " & $iLocalFile & @CRLF)

;~                  _FTP_DirCreate($iRemotePath & '\' & $iPathName)
;~                  _FTP_ProgressUpload($hFTPSession, $aDirList[$d] & '\' & $iFileName, $iRemotePath & '\' & $iPathName)

                Next
            EndIf
        Next
    EndIf

EndFunc   ;==>_Sequential

Func _IsFile($sPath)
    If Not FileExists($sPath) Then Return SetError(1, 0, -1)
    If StringInStr(FileGetAttrib($sPath), 'D') <> 0 Then
        Return SetError(0, 0, 0) ;IsDir
    Else
        Return SetError(0, 0, 1) ;IsFile
    EndIf
EndFunc   ;==>_IsFile

Func _SplitPath($sFilePath, $sReturnType = 0)
    Local $sDrive, $sDir, $sFileName, $sExtension
    Local $aArray = StringRegExp($sFilePath, "^\h*((?:\\\\\?\\)*(\\\\[^\?\/\\]+|[A-Za-z]:)?(.*[\/\\]\h*)?((?:[^\.\/\\]|(?(?=\.[^\/\\]*\.)\.))*)?([^\/\\]*))$", 1)
    If @error Then ; This error should never happen.
        ReDim $aArray[5]
        $aArray[0] = $sFilePath
    EndIf
    $sDrive = $aArray[1]
    If StringLeft($aArray[2], 1) == "/" Then
        $sDir = StringRegExpReplace($aArray[2], "\h*[\/\\]+\h*", "\/")
    Else
        $sDir = StringRegExpReplace($aArray[2], "\h*[\/\\]+\h*", "\\")
    EndIf
    $sFileName = $aArray[3]
    $sExtension = $aArray[4]
    If $sReturnType = 0 Then Return $aArray
    If $sReturnType = 1 Then Return $sDrive
    If $sReturnType = 2 Then Return $sDir
    If $sReturnType = 3 Then Return $sFileName
    If $sReturnType = 4 Then Return $sExtension
    Local $fName = $sFileName & $sExtension
    If $sReturnType = 5 Then Return $fName
    Local $zName = $sDrive & $sDir
    If $sReturnType = 6 Then Return $zName
    ; By Dao Van Trong - TRONG.LIVE
EndFunc   ;==>_SplitPath

 

Edited by VIP
Thanks Subz

Share this post


Link to post
Share on other sites

The code was based upon folder names in your first post, which does work, however it appears you want to sort by hierarchy maybe?  So can you try:

Local $aFolderPath, $x = 0
Local $aFolderPaths = _FileListToArrayRec(@ScriptDir, "*", 2, 1, 1, 2)
_ArrayColInsert($aFolderPaths, 1)
For $i = 1 To $aFolderPaths[0][0]
    $aFolderPath = StringSplit($aFolderPaths[$i][0], "\")
    If $aFolderPaths[$i - 1][1] = $aFolderPath[0] & "." & $x Then
        $x += 1
        $aFolderPaths[$i][1] = $aFolderPath[0] & "." & $x
    Else
        $x = 0
        $aFolderPaths[$i][1] = $aFolderPath[0] & "." & $x
    EndIf
Next
_ArraySort($aFolderPaths, 1, 1, 0, 1)
_ArrayDisplay($aFolderPaths)

 

Share this post


Link to post
Share on other sites

Just my luck I only tested with 9 subfolders :), you just need to turn the second value into a number, you could also use something like the following (probably could be written better) but works:

Local $aFolderPath, $x = 0
Local $aFolderPaths = _FileListToArrayRec(@ScriptDir, "*", 2, 1, 1, 2)
_ArrayColInsert($aFolderPaths, 1)
For $i = 1 To $aFolderPaths[0][0]
    $aFolderPath = StringSplit($aFolderPaths[$i][0], "\")
    If _ArraySearch($aFolderPaths, Number($aFolderPath[0] & "." & $x), 1, 0, 0, 0, 1, 1) > -1 Then
        $x += 1
        $aFolderPaths[$i][1] = Number($aFolderPath[0] & "." & $x)
    Else
        $x = 0
        While _ArraySearch($aFolderPaths, Number($aFolderPath[0] & "." & $x), 1, 0, 0, 0, 1, 1) > -1
            $x += 1
        WEnd
        $aFolderPaths[$i][1] = Number($aFolderPath[0] & "." & $x)
    EndIf
Next
_ArraySort($aFolderPaths, 1, 1, 0, 1)
_ArrayDisplay($aFolderPaths)

 

Share this post


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

  • Similar Content

    • By VIP
      Why ?

       
      Source:
      #RequireAdmin #Region #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_Change2CUI=y #EndRegion #include <Array.au3> #include <Constants.au3> #include <File.au3> ConsoleWrite("===================================================="&@CRLF) Global $Search_Key = "♡" ;~ Global $Search_Path = @ScriptDir & "\_Source\" Global $Search_Path = "A:\_Webs___\_Source\" Global $Search_FileType = '*.php;*.js;*.xml' Global $iReurn=_SearchInFile($Search_Key, $Search_Path, $Search_FileType) ConsoleWrite($iReurn & " - Error: " & @error & @CRLF) Func _SearchInFile($sSearch, $sFilePath, $sMask = '*', $fRecursive = 1, $fCaseSensitive = True) If (FileExists($sFilePath)<>1) Then Return SetError(-1, 0, 0) Else ConsoleWrite("- File " &$sFilePath&" is Exists !"& @CRLF) EndIf Local $aFileList = _FileListToArrayRec($sFilePath, $sMask, 0, $fRecursive, 1, 2) Local $iError = @error If $iError<>0 Or (IsArray($aFileList)<>1) Then Switch $iError Case 1 ConsoleWrite("! Error: 1 - Path not found or invalid" & @CRLF) Case 2 ConsoleWrite("! Error: 2 - Invalid Include parameter" & @CRLF) Case 3 ConsoleWrite("! Error: 3 - Invalid Exclude parameter" & @CRLF) Case 4 ConsoleWrite("! Error: 4 - Invalid Exclude_Folders parameter" & @CRLF) Case 5 ConsoleWrite("! Error: 5 - Invalid $iReturn parameter" & @CRLF) Case 6 ConsoleWrite("! Error: 6 - Invalid $iRecur parameter" & @CRLF) Case 7 ConsoleWrite("! Error: 7 - Invalid $iSort parameter" & @CRLF) Case 8 ConsoleWrite("! Error: 8 - Invalid $iReturnPath parameter" & @CRLF) Case 9 ConsoleWrite("! Error: 9 - No files/folders found" & @CRLF) EndSwitch Return SetError(1, 0, 0) EndIf For $i = 1 To UBound($aFileList) -1 Local $iFileContent = FileRead($aFileList[$i]) If StringInStr($iFileContent, $sSearch, $fCaseSensitive) Then ConsoleWrite($aFileList[$i] & @CRLF) EndIf Next EndFunc ;==>_SearchInFile ;~ Local $hTimer = TimerInit() ;~ Local $aArray = _FindInFile($SearchKey, $SearchPath, $SearchFileType) ; Search for 'findinfile' within the @ScripDir and only in .au3 & .txt files. ;~ ConsoleWrite(Ceiling(TimerDiff($hTimer) / 1000) & ' second(s)' & @CRLF) ;~ _ArrayDisplay($aArray) ;~ $hTimer = TimerInit() ;~ $aArray = _FindInFile('autoit', @ScriptDir, '*.au3') ; Search for 'autoit' within the @ScripDir and only in .au3 files. ;~ ConsoleWrite(Ceiling(TimerDiff($hTimer) / 1000) & ' second(s)' & @CRLF) ;~ _ArrayDisplay($aArray) ; #FUNCTION# ==================================================================================================================== ; Name ..........: _FindInFile ; Description ...: Search for a string within files located in a specific directory. ; Syntax ........: _FindInFile($sSearch, $sFilePath[, $sMask = '*'[, $fRecursive = True[, $fLiteral = Default[, ; $fCaseSensitive = Default[, $fDetail = Default]]]]]) ; Parameters ....: $sSearch - The keyword to search for. ; $sFilePath - The folder location of where to search. ; $sMask - [optional] A list of filetype extensions separated with ';' e.g. '*.au3;*.txt'. Default is all files. ; $fRecursive - [optional] Search within subfolders. Default is True. ; $fLiteral - [optional] Use the string as a literal search string. Default is False. ; $fCaseSensitive - [optional] Use Search is case-sensitive searching. Default is False. ; $fDetail - [optional] Show filenames only. Default is False. ; Return values .: Success - Returns a one-dimensional and is made up as follows: ; $aArray[0] = Number of rows ; $aArray[1] = 1st file ; $aArray[n] = nth file ; Failure - Returns an empty array and sets @error to non-zero ; Author ........: guinness ; Remarks .......: For more details: http://ss64.com/nt/findstr.html ; Example .......: Yes ; =============================================================================================================================== Func _FindInFile($sSearch, $sFilePath, $sMask = '*', $fRecursive = True, $fLiteral = Default, $fCaseSensitive = Default, $fDetail = Default) Local $sCaseSensitive = $fCaseSensitive ? '' : '/i', $sDetail = $fDetail ? '/n' : '/m', $sRecursive = ($fRecursive Or $fRecursive = Default) ? '/s' : '' If $fLiteral Then $sSearch = ' /c:' & $sSearch EndIf If $sMask = Default Then $sMask = '*' EndIf $sFilePath = StringRegExpReplace($sFilePath, '[\\/]+$', '') & '\' Local Const $aMask = StringSplit($sMask, ';') Local $iPID = 0, $sOutput = '', $sCMD = '' For $i = 1 To $aMask[0] $sCMD = 'findstr ' & $sCaseSensitive & ' ' & $sDetail & ' ' & $sRecursive & ' "' & $sSearch & '" "' & $sFilePath & $aMask[$i] & '"' ConsoleWrite("cmd: " & $sCMD & @CRLF) ;~ MsgBox(0,"",$sCMD) $iPID = Run(@ComSpec & ' /c ' & $sCMD, @SystemDir, @SW_HIDE, $STDOUT_CHILD) ProcessWaitClose($iPID) $sOutput &= StdoutRead($iPID) Next Return StringSplit(StringStripWS(StringStripCR($sOutput), BitOR($STR_STRIPLEADING, $STR_STRIPTRAILING)), @LF) EndFunc ;==>_FindInFile  
    • By careca
      Hi, i have this array of numbers in the form of strings, and i assumed _arraysort would sort them out, but theres no option to do it numerically, so i had to do it another way, seems clumsy, what am i missing here? There's for sure a better way to sort this out numerically right? _arraysort is doing a mess with the numbers, it goes like this: 35,45,50,42,48,54
      #include<Array.au3> Local $ID, $AM Local $FO = Fileopen('mult.txt') Local $FR = FileReadToArray($FO) FileClose($FO) _ArrayDisplay($FR) For $d = 0 To UBound($FR) $AM = _ArrayMin($FR, 1) ConsoleWrite($AM &@CRLF) $ID = _ArraySearch($FR, $AM) _ArrayDelete($FR, $ID) Next So this way i retrieve the lowest number and then delete it from the array, what would you do?
      mult.txt
    • By ternal
      Hi,
      Recently I have had the need to do a sort and then do a second sort while the item of the first sort stays the same ( double sorting , first on column x then while column x is the same sort column y).
      I did not put much efffort into error checking but so far I did not need it.
      For my applications so far it works perfectly however if someone is willing I want to test this extensivly.
      If anyone has big lists of random stuff to sort could you try this out please?
      #include <Array.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _ArraySort_Double ; Description ...: ; Syntax ........: _ArraySort_Double (Byref $array[, $first_index = Default[, $second_index = Default[, $ascending = Default]]]) ; Parameters ....: $array - 2d array to sort. ; $first_index - [optional] first column to sort. Default is 0. ; $second_index - [optional] second column to sort. Default is 1. ; $ascending - [optional] ascending/descending. Default is 1. ; Return values .: 1 if no errors occured , -1 if errors occured ; Author ........: Ternal ; Remarks .......: Needs excessive testing. ; Related .......: _arraysort() ; =============================================================================================================================== Func _ArraySort_Double (byref $array, $first_index = Default, $second_index = Default, $ascending = Default) Local $temp_value Local $counter = 1 If UBound($array, $UBOUND_DIMENSIONS) <> 2 Then MsgBox(0, "error", "error") return -1 EndIf If $first_index = Default Then $first_index = 0 If $second_index = Default Then $second_index = 1 If $ascending = Default Then $ascending = 1 _ArraySort($array, $ascending, 0, 0, $first_index); you can alter settings of primary sort here If @error Then MsgBox(0, "error", @error) return -1 EndIf $temp_value = $array[0][$first_index] For $x = 1 to UBound($array, 1) - 1 If Mod( $x, 10000) = 0 Then ConsoleWrite("at " & $x & " of a total : " & UBound($array, 1) & @CRLF) If $array[$x][$first_index] = $temp_value Then $counter+= 1 If $x = UBound($array, 1) - 1 Then; do last line here(if last line is not a new item) _ArraySort($array, $ascending, $x - $counter, $x, $second_index);you can alter settings of secondary sort here(don't forget to place line 34 the exact same) If @error Then MsgBox(0, "error", @error) return -1 EndIf EndIf Else If $counter > 0 Then ;at least 2 of the same _ArraySort($array, $ascending, $x - $counter, $x - 1, $second_index);you can alter settings of secondary sort here(don't forget to place line 29 the exact same) If @error Then MsgBox(0, "error", @error) return -1 EndIf $counter = 1 EndIf EndIf $temp_value = $array[$x][$first_index] Next Return 1 EndFunc Kind regards, Ternal
    • By TimRude
      The help text for the _ArrayDisplay function says: "Clicking on a column header sort it."
      I'm wondering why the sorting of hex numbers (specifically window handles like 0x12345678) is so wonky.
      Sample script:
      #include <Array.au3> Local $aList = WinList() _ArrayDisplay($aList) Clicking on the Col1 header to sort by window handle doesn't properly sort the list.
      As a workaround, I'm sorting the array by window handle before displaying it using _ArraySort. But I still wonder what's up with the ListView sorting.
      Workaround:
      #include <Array.au3> Local $aList = WinList() _ArraySort($aList, 0, 1, 0, 1) _ArrayDisplay($aList)  
    • By Skysnake
      I am tracking this topic by @LarsJ.  It is very advanced and overkill for what I am currently trying to do.
       
      Problem is this.
      Listview contains columns, one of which is right aligned and gets populated by float values, such as 123.99.  Some do not have decimals ie 124.00 and on sort gets truncated to 124.  Its obviously still the same value, but the display has reset.
      ; line below is for list VIEW ;..................................0.........1......2............ $cListView = GUICtrlCreateListView("CUSTOMER|AMOUNT|DESCRIPTION", 8, 152, 764, 279) GUICtrlSetBkColor($cListView, $GUI_BKCOLOR_LV_ALTERNATE) ; alternate between the listview background color and the listview item background color GUICtrlSetBkColor($cListView, $LVStdClr) ; Set the background color for the listview _GUICtrlListView_SetColumnWidth($cListView, 0, 120) ; -- the client name _GUICtrlListView_SetColumnWidth($cListView, 1, 90) ;-- the amount _GUICtrlListView_JustifyColumn($cListView, 1, 1) ; 1 - Text is right aligned _GUICtrlListView_SetColumnWidth($cListView, 2, 200) ; the description What I am looking for is something native and simple like a 
          _GUICtrlListView_SetColumnFormat($cListView, 1, "%.2f") ;  1 - column is stringformatted to "%.2f"
      So that after each sort it will appear as it was in the original rendering.
      Is there something like this? I have not been able to find a simple solution.

      Thanks.
      Skysnake
×
×
  • Create New...