Sign in to follow this  
Followers 0
asgarcymed

Script to detect directories which only have par2 files

15 posts in this topic

Inside a main folder I have many subfolders, which have many more sub-subfolders with files...

I need to recursively seek all files => get all file extensions inside each directory =>

=> If "*.par2 is the only extension in this directory" Then

Make CSV file with:

Path,Par2's File(s)Name

Or either - I want to report all directories which only have *.par2 files.

Can you please help me? I feel confused...

Thanks.

Regards.


MLMK - my blogging craziness...

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

So you want a recursive search, but you only want it to return dirs with *.par2

Is that corect?

hmmmm.....

Edited by DBak

[center][/center]

Share this post


Link to post
Share on other sites

Maybe the scripts mentioned in this post can help you getting started


If you learn from It, it's not a mistake

Share this post


Link to post
Share on other sites

So try this out....

Btw: I'm not the author

;RUN FUCNTION AND DISPLAYE RESULTS
#include <array.au3>
$test = _FileListToArrayEx( $folder, "*.par2", 0, -1, True );$folder, *.par2, 0, no excludes, do recursive search
_ArrayDisplay( $test )
;END OF RUN FUNCTION

Func _FileListToArrayEx($sPath, $sFilter = '*.*', $iFlag = 0, $sExclude = '', $iRecurse = False)
    If Not FileExists($sPath) Then Return SetError(1, 1, '')
    If $sFilter = -1 Or $sFilter = Default Then $sFilter = '*.*'
    If $iFlag = -1 Or $iFlag = Default Then $iFlag = 0
    If $sExclude = -1 Or $sExclude = Default Then $sExclude = ''
    Local $aBadChar[6] = ['\', '/', ':', '>', '<', '|']
    $sFilter = StringRegExpReplace($sFilter, '\s*;\s*', ';')
    If StringRight($sPath, 1) <> '\' Then $sPath &= '\'
    For $iCC = 0 To 5
        If StringInStr($sFilter, $aBadChar[$iCC]) Or _
            StringInStr($sExclude, $aBadChar[$iCC]) Then Return SetError(2, 2, '')
    Next
    If StringStripWS($sFilter, 8) = '' Then Return SetError(2, 2, '')
    If Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(3, 3, '')
    Local $oFSO = ObjCreate("Scripting.FileSystemObject"), $sTFolder
    $sTFolder = $oFSO.GetSpecialFolder(2)
    Local $hOutFile = @TempDir & $oFSO.GetTempName
    If Not StringInStr($sFilter, ';') Then $sFilter &= ';'
    Local $aSplit = StringSplit(StringStripWS($sFilter, 8), ';'), $sRead, $sHoldSplit
    For $iCC = 1 To $aSplit[0]
        If StringStripWS($aSplit[$iCC],8) = '' Then ContinueLoop
        If StringLeft($aSplit[$iCC], 1) = '.' And _
            UBound(StringSplit($aSplit[$iCC], '.')) - 2 = 1 Then $aSplit[$iCC] = '*' & $aSplit[$iCC]
        $sHoldSplit &= '"' & $sPath & $aSplit[$iCC] & '" '
    Next
    $sHoldSplit = StringTrimRight($sHoldSplit, 1)
    If $iRecurse Then
        RunWait(@Comspec & ' /c dir /b /s /a ' & $sHoldSplit & ' > "' & $hOutFile & '"', '', @SW_HIDE)
    Else
        RunWait(@ComSpec & ' /c dir /b /a ' & $sHoldSplit & ' /o-e /od > "' & $hOutFile & '"', '', @SW_HIDE)
    EndIf
    $sRead &= FileRead($hOutFile)
    If Not FileExists($hOutFile) Then Return SetError(4, 4, '')
    FileDelete($hOutFile)
    If StringStripWS($sRead, 8) = '' Then SetError(4, 4, '')
    Local $aFSplit = StringSplit(StringTrimRight(StringStripCR($sRead), 1), @LF)
    Local $sHold
    For $iCC = 1 To $aFSplit[0]
        If $sExclude And StringLeft($aFSplit[$iCC], _
            StringLen(StringReplace($sExclude, '*', ''))) = StringReplace($sExclude, '*', '') Then ContinueLoop
        Switch $iFlag
            Case 0
                If StringRegExp($aFSplit[$iCC], '\w:\\') = 0 Then
                    $sHold &= $sPath & $aFSplit[$iCC] & Chr(1)
                Else
                    $sHold &= $aFSplit[$iCC] & Chr(1)
                EndIf
            Case 1
                If StringInStr(FileGetAttrib($sPath & '\' & $aFSplit[$iCC]), 'd') = 0 And _
                    StringInStr(FileGetAttrib($aFSplit[$iCC]), 'd') = 0 Then
                    If StringRegExp($aFSplit[$iCC], '\w:\\') = 0 Then
                        $sHold &= $sPath & $aFSplit[$iCC] & Chr(1)
                    Else
                        $sHold &= $aFSplit[$iCC] & Chr(1)
                    EndIf
                EndIf
            Case 2
                If StringInStr(FileGetAttrib($sPath & '\' & $aFSplit[$iCC]), 'd') Or _
                    StringInStr(FileGetAttrib($aFSplit[$iCC]), 'd') Then
                    If StringRegExp($aFSplit[$iCC], '\w:\\') = 0 Then
                        $sHold &= $sPath & $aFSplit[$iCC] & Chr(1)
                    Else
                        $sHold &= $aFSplit[$iCC] & Chr(1)
                    EndIf
                EndIf
        EndSwitch
    Next
    If StringTrimRight($sHold, 1) Then Return StringSplit(StringTrimRight($sHold, 1), Chr(1))
    Return SetError(4, 4, '')
EndFunc

[center][/center]

Share this post


Link to post
Share on other sites

Thank you very much for answering!! ,)

DBak - the script you posted lists an array with recursive list of all *.par2; but NOT only directories which only have *.par2 files... Now what?

Regards.


MLMK - my blogging craziness...

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

This is all you need: Found this in Google search the other day, check it out for explanations... http://dailycupoftech.com/folder-recursion-in-autoit/

EDITED:

;Recursive File Lister

Dim $FolderName = @ScriptDir
Dim $FileCount = 0

ScanFolder($FolderName)

MsgBox(0,"Done","Folder Scan Complete.  Scanned " & $FileCount & " Files")
ToolTip('') 
If FileExists(@ScriptDir & "\FileList.txt") Then ShellExecuteWait(@ScriptDir & "\FileList.txt"); open log

Func ScanFolder($SourceFolder)
    Local $Search
    Local $File
    Local $FileAttributes
    Local $FullFilePath
    
    $Search = FileFindFirstFile($SourceFolder & "\*.*")  

    While 1
        If $Search = -1 Then
            ExitLoop
        EndIf
        
        $File = FileFindNextFile($Search)
        If @error Then ExitLoop
        
        $FullFilePath = $SourceFolder & "\" & $File
        $FileAttributes = FileGetAttrib($FullFilePath)
        
        If StringInStr($FileAttributes,"D") Then ;if its a folder then ....
            ScanFolder($FullFilePath)
        Else
            If StringInStr($File,'.part2') Then LogFile($FullFilePath) ; if its a file & has '.part2' in its filename then...
            ToolTip($FullFilePath,0,0)          

        EndIf

    WEnd

    FileClose($Search)
EndFunc

Func LogFile($FileName)
    FileWriteLine(@ScriptDir & "\FileList.txt",$FileName)
    $FileCount += 1
    ToolTip($FileName,0,0)
EndFunc
Edited by goldenix

My Projects:[list][*]Guide - ytube step by step tut for reading memory with autoitscript + samples[*]WinHide - tool to show hide windows, Skinned With GDI+[*]Virtualdub batch job list maker - Batch Process all files with same settings[*]Exp calc - Exp calculator for online games[*]Automated Microsoft SQL Server 2000 installer[*]Image sorter helper for IrfanView - 1 click opens img & move ur mouse to close opened img[/list]

Share this post


Link to post
Share on other sites

goldenix - thank you for answering and posting a so very good URL ("Daily Cup of Tech") ^_^

Recursion in AutoIt always have been a nightmare for me... :)

Any good tutorial about recursion is always welcome to me :)

Nevertheless, this concrete problem remains unsolved... This script you posted has the same problem as DBak's one <=> it recursively lists list all *.par2 files; but NOT ONLY inside directories which ONLY have *.par2 files...

Example:

Main\Dir1\01.rar

Main\Dir1\02.par2

Main\Dir2\03.par2

Dir1 does not matter because have other extensions (rar); NOT ONLY par2

Dir2 is what I want => no other extension exist; ONLY par2

Does anyone have a brilliant idea how to do this?

I really need it, but my knowledge is not enough ;(

Please help...

Thanks.

Regards


MLMK - my blogging craziness...

Share this post


Link to post
Share on other sites

hi,

It may not be efficient, but this would work!

1. Make a list of all directories, including subdirectories you want to check ("folder flag is 2 in the UDF "FileListToArrayFast", link in my signature)

2. Loop though all those directories in the array, running filelist to array on each directory with filter "par2" or whatever (file flag is "1"); delete any directories in the array which have no files returned.

3. Use the modified Array list of directories to loop though all those directories in the array, running filelist to array on each directory with filter "*", and "exclude" parameter set to "par2" ; delete any directories which have any files returned!

4. This gives the Array of Directories with -only- "par2" files; Make a new full list of files by looping if you want.

best, randall

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Ok this thig works basically, if i understood you right, but it does not search in the right order for some reason, so it may write some folders 2 or more times,, this is wierd, must be autoit bug....Anyway its only a mather of the way you make it write the data to file... hire is the code:

;Recursive File Lister

#include <Array.au3>
Dim $avArray[1]
Dim $FolderName = @ScriptDir
Dim $FileCount = 0
Dim $fullpath, $s_folder, $_file

_ArrayAdd( $avArray,'_') ; need to add something to array or it will eror... 
FileDelete(@ScriptDir & "\FileList.txt")

ScanFolder($FolderName)

MsgBox(0,"Done","Folder Scan Complete.  Scanned " & $FileCount & " Files")
If FileExists(@ScriptDir & "\FileList.txt") Then ShellExecute(@ScriptDir & "\FileList.txt"); open log

Func ScanFolder($SourceFolder)
    Local $Search
    Local $File
    Local $FileAttributes
    Local $FullFilePath
    
    $Search = FileFindFirstFile($SourceFolder & "\*.*")  

    While 1
        If $Search = -1 Then
            ExitLoop
        EndIf
        
        $File = FileFindNextFile($Search)
        If @error Then ExitLoop
        
        $FullFilePath = $SourceFolder & "\" & $File
        $FileAttributes = FileGetAttrib($FullFilePath)
        
        $s_folder = $SourceFolder
        $_file = $File
        Dim $_file, $s_folder
        
        If StringInStr($FileAttributes,"D") Then ; if its a folder then
            ScanFolder($FullFilePath)
        Else
            If StringInStr($File,'.part2') Then ;if found text in file Then
                LogFile($FullFilePath) 
            EndIf
        EndIf

    WEnd
    FileClose($Search)
EndFunc

Func LogFile($FileName)
    
    $Remove_dir = StringReplace($s_folder,@ScriptDir,"@scriptdir") ; cut the folddername so it will start from Scriptdir

        If $s_folder <> $avArray[1] Then ; if folder not equal to the foldername in the array then
            FileWrite(@ScriptDir & "\FileList.txt", @CRLF & $Remove_dir & "\" & @CRLF) 
            _ArrayDelete( $avArray,1)
            _ArrayInsert( $avArray,1,$s_folder)
        EndIf
            FileWrite(@ScriptDir & "\FileList.txt",$_file  & @CRLF) 
            $FileCount += 1
EndFunc
Edited by goldenix

My Projects:[list][*]Guide - ytube step by step tut for reading memory with autoitscript + samples[*]WinHide - tool to show hide windows, Skinned With GDI+[*]Virtualdub batch job list maker - Batch Process all files with same settings[*]Exp calc - Exp calculator for online games[*]Automated Microsoft SQL Server 2000 installer[*]Image sorter helper for IrfanView - 1 click opens img & move ur mouse to close opened img[/list]

Share this post


Link to post
Share on other sites

Are you wanting the folders returned, or paths to the files?

Share this post


Link to post
Share on other sites

Are you wanting the folders returned, or paths to the files?

I think he wants it like this:

@scriptdir\links\
wrx-dbzt2.part01.rar
wrx-dbzt2.part02.rar

@scriptdir\links\PS2DVD - DBZ Budokai Tenkaichi\
wrx-dbzt2.part01.rar
wrx-dbzt2.part02.rar

Yet the colde I posted does it like this: Note that there are 2 links folders in the list & half of the files are hire & there...:

@scriptdir\links\
wrx-dbzt2.part01.rar

@scriptdir\links\PS2DVD - DBZ Budokai Tenkaichi\
wrx-dbzt2.part01.rar
wrx-dbzt2.part02.rar

@scriptdir\links\
wrx-dbzt2.part02.rar

My Projects:[list][*]Guide - ytube step by step tut for reading memory with autoitscript + samples[*]WinHide - tool to show hide windows, Skinned With GDI+[*]Virtualdub batch job list maker - Batch Process all files with same settings[*]Exp calc - Exp calculator for online games[*]Automated Microsoft SQL Server 2000 installer[*]Image sorter helper for IrfanView - 1 click opens img & move ur mouse to close opened img[/list]

Share this post


Link to post
Share on other sites

That seems to be the norm. It does it with some of mine. I think it has to do with the way windows sorts the files internally.

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

This should overcome duplicate folders being inserted into the array. You can comment out the line at the bottom of the first function if you don't want folder names in the array at all, or comment the line below that if you only want folder names containing only pars.

#cs ----------------------------------------------------------------------------
    
    AutoIt Version: 3.2.8.1
    Author:         WeaponX
    
    Script Function:
    Recursive file search with helper function (string based)
    
    Notes:
    -StringSplit is faster than ReDim
    
#ce ----------------------------------------------------------------------------

#include <array.au3>
$timestamp = TimerInit()
$Array = FileListToArrayX ("D:\temp", "(?i)\.(par)")
;MsgBox(0, "", (TimerDiff($timestamp) / 1000) & " seconds");0.1797s / 2090 files
_ArrayDisplay($Array)

Func FileListToArrayX ($FLTAXstartDir, $RFSpattern = ".")
    Local $FLTAXstring = ""

    ;Retrieve array of all folders
    $folderArray = RecursiveFolderSearch ($FLTAXstartDir)

    ;Loop through all folders
    For $X = 1 To $folderArray[0]
        $search = FileFindFirstFile($folderArray[$X] & "\*.*")
        If @error Then ContinueLoop

        $temp = ""
        
        ;Search through all files and folders in directory
        While 1
            $next = FileFindNextFile($search)
            If @error Then ExitLoop

            ;Skip folders, append to string of all filenames
            If Not StringInStr(FileGetAttrib($folderArray[$X] & "\" & $next), "D") Then 
                If StringRegExp($next,$RFSpattern, 0) Then
                    $temp &= $folderArray[$X] & "\" & $next & "*"
                Else
                    $temp = ""
                    ExitLoop
                EndIf
            EndIf
        WEnd
        
        If $temp <> "" Then
            ;Store path to folder (Comment out if you don't want the folder path in the array)
            $FLTAXstring &= $folderArray[$X] & "*"
            
            ;Store paths to files
            $FLTAXstring &= $temp
        EndIf
        FileClose($search)
    Next

    ;Split string into array and return it
    Return StringSplit(StringTrimRight($FLTAXstring, 1), "*")
EndFunc   ;==>FileListToArrayX

Func RecursiveFolderSearch ($startDir, $depth = 0)
    If $depth = 0 Then Global $RFSstring = $startDir & "*" 

    $search = FileFindFirstFile($startDir & "\*.*")
    If @error Then Return

    ;Search through all files and folders in directory
    While 1
        $next = FileFindNextFile($search)
        If @error Then ExitLoop

        ;If folder, recurse
        If StringInStr(FileGetAttrib($startDir & "\" & $next), "D") Then

            ;Append foldername to string
            $RFSstring &= $startDir & "\" & $next & "*" 

            ;Recurse
            RecursiveFolderSearch ($startDir & "\" & $next, $depth + 1)
        EndIf
    WEnd
    FileClose($search)

    If $depth = 0 Then Return StringSplit(StringTrimRight($RFSstring, 1), "*")
EndFunc   ;==>RecursiveFolderSearch
Edited by weaponx

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

Hi,

Subsequent to my post above; ? this;

#include-once
#include<array.au3>
#include<_FileListToArrayFaster1d.au3>; has bug with retained @Cr, so strip them
;1================================================================
Local $sStringArray, $ar_DirArray = _FileListToArray3(@ScriptDir, "*", 2, 1) 
_ArrayInsert($ar_DirArray,1,@ScriptDir) 
;~ _ArrayDisplay($ar_DirArray)
;2================================================================
For $i = UBound($ar_DirArray) - 1 To 1 Step - 1
    $ar_TempArray = _FileListToArray3(StringStripCR($ar_DirArray[$i]), ".au3", 1, 0)  
    If Not IsArray($ar_TempArray) Or $ar_TempArray[1] == "" Then _ArrayDelete($ar_DirArray, $i)
Next
$ar_DirArray[0] = UBound($ar_DirArray) - 1
;~ _ArrayDisplay($ar_DirArray,"Deleted if no au3 files")
;3================================================================
For $i = UBound($ar_DirArray) - 1 To 1 Step - 1
    $ar_TempArray = _FileListToArray3(StringStripCR($ar_DirArray[$i]), "*", 1, 0, 1, ".au3") 
    If IsArray($ar_TempArray) And $ar_TempArray[1] <> "" Then _ArrayDelete($ar_DirArray, $i)
Next
$ar_DirArray[0] = UBound($ar_DirArray) - 1
;~ _ArrayDisplay($ar_DirArray,"Deleted if other files than  au3 files")
;4================================================================
For $i = 1 To UBound($ar_DirArray) - 1
    $ar_FinalArray = _FileListToArray3(StringStripCR($ar_DirArray[$i]), "*", 1, 0) 
    $sStringArray &= _ArrayToString($ar_FinalArray, "*", 1)
Next
$ar_FinalArray = StringSplit($sStringArray, "*")
_ArrayDisplay($ar_FinalArray,"Final List")oÝ÷ Øay"¶+jÌ­¢éÝz»-jwZÙ¨v'òùè¶Ø^}«-zËAzËkjwZ
Would no it

Best, Randall

Edited by randallc

Share this post


Link to post
Share on other sites

First, I want to thank to all of you for your help!

My problem was perfectly solved using the last script that WeaponX posted; and I learned a lot with all your posts!

Recursion in AutoIt continues to be a very hard task for me; but I feel very enthusiastic to learn it deeply, with your help! I most use AutoIt for Files and Folders managing, thus recursion is very important for me :)

Thank you very much!

Best regards.


MLMK - my blogging craziness...

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
Sign in to follow this  
Followers 0