asgarcymed Posted December 3, 2007 Share Posted December 3, 2007 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... Link to comment Share on other sites More sharing options...
DirtDBaK Posted December 3, 2007 Share Posted December 3, 2007 (edited) So you want a recursive search, but you only want it to return dirs with *.par2 Is that corect? hmmmm..... Edited December 3, 2007 by DBak [center][/center] Link to comment Share on other sites More sharing options...
Scriptonize Posted December 3, 2007 Share Posted December 3, 2007 Maybe the scripts mentioned in this post can help you getting started If you learn from It, it's not a mistake Link to comment Share on other sites More sharing options...
DirtDBaK Posted December 3, 2007 Share Posted December 3, 2007 So try this out.... Btw: I'm not the author expandcollapse popup;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] Link to comment Share on other sites More sharing options...
asgarcymed Posted December 3, 2007 Author Share Posted December 3, 2007 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... Link to comment Share on other sites More sharing options...
goldenix Posted December 3, 2007 Share Posted December 3, 2007 (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:expandcollapse popup;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 December 3, 2007 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] Link to comment Share on other sites More sharing options...
asgarcymed Posted December 3, 2007 Author Share Posted December 3, 2007 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... Link to comment Share on other sites More sharing options...
randallc Posted December 4, 2007 Share Posted December 4, 2007 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 ExcelCOM... AccessCom.. Word2... FileListToArrayNew...SearchMiner... Regexps...SQL...Explorer...Array2D.. _GUIListView...array problem...APITailRW Link to comment Share on other sites More sharing options...
goldenix Posted December 4, 2007 Share Posted December 4, 2007 (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: expandcollapse popup;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 December 4, 2007 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] Link to comment Share on other sites More sharing options...
weaponx Posted December 4, 2007 Share Posted December 4, 2007 Are you wanting the folders returned, or paths to the files? Link to comment Share on other sites More sharing options...
goldenix Posted December 4, 2007 Share Posted December 4, 2007 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] Link to comment Share on other sites More sharing options...
weaponx Posted December 4, 2007 Share Posted December 4, 2007 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. Link to comment Share on other sites More sharing options...
weaponx Posted December 4, 2007 Share Posted December 4, 2007 (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. expandcollapse popup#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 December 4, 2007 by weaponx Link to comment Share on other sites More sharing options...
randallc Posted December 4, 2007 Share Posted December 4, 2007 (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ËkjwZWould no it Best, Randall Edited December 4, 2007 by randallc ExcelCOM... AccessCom.. Word2... FileListToArrayNew...SearchMiner... Regexps...SQL...Explorer...Array2D.. _GUIListView...array problem...APITailRW Link to comment Share on other sites More sharing options...
asgarcymed Posted December 4, 2007 Author Share Posted December 4, 2007 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... Link to comment Share on other sites More sharing options...
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