avery Posted December 3, 2009 Share Posted December 3, 2009 Hello au3 Gurus' I normally code in PERL but slowly moving over to au3 for my projects. In PERL I normally use use File::Find; Find(\&findFiles, $path2Search); And that would give me everything (folders and files) under that path. In au3 I've tried to code the logic myself by using FilefindFirst and then saying If the item is a folder then to run the function for that folder an so forth but I end up with endless loops and broken code. It makes my brain hurt. Can anyone please help or have a UDF for this? ; Shows the filenames of all files in the current directory $search = FileFindFirstFile("c:\abox\temp\*.*") ; Check if the search was successful If $search = -1 Then MsgBox(0, "Error", "No files/directories matched the search pattern") Exit EndIf While 1 $file = FileFindNextFile($search) If @error Then ExitLoop ConsoleWrite("var => " & $file & @CR) WEnd ; Close the search handle FileClose($search) Respectfully, Avery Howell www.abox.orgAvery HowellVisit My AutoIt Websitehttp://www.abox.org Link to comment Share on other sites More sharing options...
weaponx Posted December 3, 2009 Share Posted December 3, 2009 Search for recursive _FileListToArray in Example Scripts. Here is one I made: http://www.autoitscript.com/forum/index.php?showtopic=58558 Link to comment Share on other sites More sharing options...
smartee Posted December 3, 2009 Share Posted December 3, 2009 A couple examples to look at hereexamples Link to comment Share on other sites More sharing options...
avery Posted December 3, 2009 Author Share Posted December 3, 2009 (edited) I will look at the examples now. While I was still looking for alternate solutions I came across maybe using an external command: C:\abox>dir /Q /S /B Shows all files and does it very quickly. However, I have never tried to capture and parse the console output in au3 or if it's even possible. Does anyone have a suggestion on the pro's and cons of using an external command like "dir" are? Thanks for the fast replies. I will check out the recursive examples. I forgot to mention I did a search before I posted and didn't find anything that would suffice. I will click these links before I go any further. Thanks! Avery Howell Edited December 3, 2009 by avery www.abox.orgAvery HowellVisit My AutoIt Websitehttp://www.abox.org Link to comment Share on other sites More sharing options...
Mat Posted December 3, 2009 Share Posted December 3, 2009 (edited) Func _Find ($s, $d = @HomeDrive) If StringRight ($d, 1) <> "\" Then $d &= "\" Local $h = FileFindFirstFile ($d & "*") If $h = -1 Then Return 0 while 1 $t = FileFindNextFile ($h) If $t = $s Then Return $d & $t $t = $d & $t If @Error Then Return 0 * FileClose ($h) If StringInStr (FileGetAttrib ($t), "D") Then $tmp = _Find ($s, $t) If $tmp <> "0" Then Return $tmp ContinueLoop EndIf WEnd FileClose ($h) Return 0 EndFunc ; ==> _Find Func _FindAll ($s, $d = @HomeDrive) If Not IsDeclared ("sRet") Then Global $FIND_RETURN = "" EndIf If StringRight ($d, 1) <> "\" Then $d &= "\" Local $h = FileFindFirstFile ($d & "*") If $h = -1 Then Return "" while 1 $t = FileFindNextFile ($h) If @Error Then ExitLoop If $t = $s Then $FIND_RETURN &= @CRLF & $d & $t $t = $d & $t If StringInStr (FileGetAttrib ($t), "D") Then _FindAll ($s, $t) WEnd FileClose ($h) Return $FIND_RETURN EndFunc ; ==> _FindAll Are the ones I use (by me), A good alternative would be to use Cmd and read StdOut. Local $sCommand = "dir C:\test.au3 /w/o/s/p" MsgBox (0, "text files in drive C:", _RunCmd ($sCommand)) Func _RunCmd ($sCommand) If StringLeft ($sCommand, 1) = " " Then $sCommand = " " & $sCommand Local $nPid = Run (@Comspec & " /c " & $sCommand, "", @SW_Hide, 8), $sRet = "" If @Error then Return "ERROR:" & @ERROR ProcessWait ($nPid) While 1 $sRet &= StdoutRead($nPID) If @error Or (Not ProcessExists ($nPid)) Then ExitLoop WEnd Return $sRet EndFunc ; ==> _RunCmd It takes a while to complete, and I have not bothered to pass the return yet. Mat Edited December 3, 2009 by Mat AutoIt Project Listing Link to comment Share on other sites More sharing options...
avery Posted December 3, 2009 Author Share Posted December 3, 2009 (edited) My Solution: http://www.autoitscript.com/forum/index.php?showtopic=33930&st=20 Thanks! Gotta Love the au3 community (: @Mat: I didn't see your post until I already made this one, sorry. I will check out those. they look much smaller/shorter then the one I have. Thanks! Credit goes to Smoke_N expandcollapse popupFunc _FileListToArrayEx($s_path, $s_mask = "*.*", $i_flag = 0, $s_exclude = -1, $f_recurse = True, $f_full_path = True) If FileExists($s_path) = 0 Then Return SetError(1, 1, 0) ; Strip trailing backslash, and add one after to make sure there's only one $s_path = StringRegExpReplace($s_path, "[\\/]+\z", "") & "\" ; Set all defaults If $s_mask = -1 Or $s_mask = Default Then $s_mask = "*.*" If $i_flag = -1 Or $i_flag = Default Then $i_flag = 0 If $s_exclude = -1 Or $s_exclude = Default Then $s_exclude = "" ; Look for bad chars If StringRegExp($s_mask, "[\\/ :> <\|]") Or StringRegExp($s_exclude, "[\\/ :> <\|]") Then Return SetError(2, 2, 0) EndIf ; Strip leading spaces between semi colon delimiter $s_mask = StringRegExpReplace($s_mask, "\s*;\s*", ";") If $s_exclude Then $s_exclude = StringRegExpReplace($s_exclude, "\s*;\s*", ";") ; Confirm mask has something in it If StringStripWS($s_mask, 8) = "" Then Return SetError(2, 2, 0) If $i_flag < 0 Or $i_flag > 2 Then Return SetError(3, 3, 0) ; Validate and create path + mask params Local $a_split = StringSplit($s_mask, ";"), $s_hold_split = "" For $i = 1 To $a_split[0] If StringStripWS($a_split[$i], 8) = "" Then ContinueLoop If StringRegExp($a_split[$i], "^\..*?\..*?\z") Then $a_split[$i] &= "*" & $a_split[$i] EndIf $s_hold_split &= '"' & $s_path & $a_split[$i] & '" ' Next $s_hold_split = StringTrimRight($s_hold_split, 1) If $s_hold_split = "" Then $s_hold_split = '"' & $s_path & '*.*"' Local $i_pid, $s_stdout, $s_hold_out, $s_dir_file_only = "", $s_recurse = "/s " If $i_flag = 1 Then $s_dir_file_only = ":-d" If $i_flag = 2 Then $s_dir_file_only = " :D " If Not $f_recurse Then $s_recurse = "" $i_pid = Run(@ComSpec & " /c dir /b " & $s_recurse & "/a" & $s_dir_file_only & " " & $s_hold_split, "", @SW_HIDE, 4 + 2) While 1 $s_stdout = StdoutRead($i_pid) If @error Then ExitLoop $s_hold_out &= $s_stdout WEnd $s_hold_out = StringRegExpReplace($s_hold_out, "\v+\z", "") If Not $s_hold_out Then Return SetError(4, 4, 0) ; Parse data and find matches based on flags Local $a_fsplit = StringSplit(StringStripCR($s_hold_out), @LF), $s_hold_ret $s_hold_out = "" If $s_exclude Then $s_exclude = StringReplace(StringReplace($s_exclude, "*", ".*?"), ";", "|") For $i = 1 To $a_fsplit[0] If $s_exclude And StringRegExp(StringRegExpReplace( _ $a_fsplit[$i], "(.*?[\\/]+)*(.*?\z)", "\2"), "(?i)" & $s_exclude) Then ContinueLoop If StringRegExp($a_fsplit[$i], "^\w:[\\/]+") = 0 Then $a_fsplit[$i] = $s_path & $a_fsplit[$i] If $f_full_path Then $s_hold_ret &= $a_fsplit[$i] & Chr(1) Else $s_hold_ret &= StringRegExpReplace($a_fsplit[$i], "((?:.*?[\\/]+)*)(.*?\z)", "$2") & Chr(1) EndIf Next $s_hold_ret = StringTrimRight($s_hold_ret, 1) If $s_hold_ret = "" Then Return SetError(5, 5, 0) Return StringSplit($s_hold_ret, Chr(1)) EndFunc Edited December 3, 2009 by avery www.abox.orgAvery HowellVisit My AutoIt Websitehttp://www.abox.org Link to comment Share on other sites More sharing options...
Mat Posted December 3, 2009 Share Posted December 3, 2009 His function is just a much better version of my second example AutoIt Project Listing Link to comment Share on other sites More sharing options...
PartyPooper Posted December 4, 2009 Share Posted December 4, 2009 Have you tried using the native DOS command and shunting the output to a text file? Something like: #Include <Array.au3> #Include <File.au3> Global $sHDD, $sfilename, $aOutput $sHDD = "C:\" $sfilename = "HOSTS" RunWait(@ComSpec & " /c " & "dir " & $sHDD & $sfilename & " /B /S > output.txt", @DesktopDir, @SW_HIDE) _FileReadToArray(@DesktopDir & "\output.txt", $aOutput) If FileExists(@DesktopDir & "\output.txt") Then FileDelete(@DesktopDir & "\output.txt") _ArrayDisplay($aOutput) Link to comment Share on other sites More sharing options...
MvGulik Posted January 15, 2010 Share Posted January 15, 2010 (edited) whatever Edited February 7, 2011 by MvGulik "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ... Link to comment Share on other sites More sharing options...
UEZ Posted January 16, 2010 Share Posted January 16, 2010 (edited) Here a recursive variant: expandcollapse popup#include <Array.au3> Dim $ergebnis[1] $path = @WindowsDir $file = ".log" ;to search for any file use "*" ;~ $ergebnis = File_Seeker($path, $file, $ergebnis, 0, 1) ;searchs for ".log" (exact search) ;~ $ergebnis = File_Seeker($path, $file, $ergebnis, 0, 0, 1, 0) ;searchs for "*.log*" recursively but dir names are excluded ;~ $ergebnis = File_Seeker($path, $file, $ergebnis, 0, 0, 0, 0) ;searchs for "*.log*" but not recursive and no dir names $ergebnis = File_Seeker($path, $file, $ergebnis, 1) ;searchs for files with extension .log but dir names are excluded If Not @error Then ;~ _ArraySort($ergebnis) _ArrayDisplay($ergebnis) ;~ Local $log ;~ For $i = 1 To UBound($ergebnis) - 1 ;~ $log &= $ergebnis[$i] & @CRLF ;~ Next ;~ $file = FileOpen(@ScriptDir & "\Ergebnis.log", 1) ;~ FileWrite($file, $log) ;~ FileClose($file) EndIf Exit ;================================================================================================== ; Function Name: File_Seeker($path, $file, $array) ; Description: searchs for a file recursively on given drive ; Parameter(s): $path path where to search ; $file filename to search for ; $array to save the search results ; $ext search for file extension, e.g. .mp3 ; $exact to search for exact file name (not case sensitive) ; $rec to search recursively for files and folders ; $folder include also folder names to search pattern ; Return Value(s): an array with the full path of the files, $array[0] = amount of found files ; Version: v0.85 Build 2010-11-30 Beta ; Author(s): UEZ ;================================================================================================== Func File_Seeker($path, $file, ByRef $aResults, $ext = 0, $exact = 0, $rec = 1, $folder = 0) Local $extended If $file <> "" And IsArray($aResults) And BitAND($ext, $exact) <> 1 Then If StringLeft($path, 2) = "\\" Or (StringRegExp(StringLeft($path, 1), "(?i:[A-Z])") And StringMid($path, 2, 1) = ":") Then If StringRight($path, 1) <> "\" Then $path &= "\" Local $seek, $suffix = "" Local $search = FileFindFirstFile($path & "*") If $search = -1 Then Return SetError(2) EndIf While 1 $seek = FileFindNextFile($search) $extended = @extended If @error Then ExitLoop If $extended And $rec Then File_Seeker($path & $seek & "\", $file, $aResults, $ext, $exact, $rec, $folder) If $exact And Not $ext Then If $seek = $file Then _ArrayAdd($aResults, $path & $seek) Else If $ext Then If StringRegExp($seek, "(?i:\" & $file & "+$\b)") And StringLeft($file, 1) = "." Then If ($extended And $folder) Or Not $extended Then _ArrayAdd($aResults, $path & $seek) EndIf Else If $file = "*" Then If ($extended And $folder) Or Not $extended Then _ArrayAdd($aResults, $path & $seek) Else If StringInStr($file, ".") Then If StringRegExp($seek, "(?i:\" & $file & ")+") Then If ($extended And $folder) Or Not $extended Then _ArrayAdd($aResults, $path & $seek) EndIf Else If StringRegExp($seek, "(?i:" & $file & ")+") Then If ($extended And $folder) Or Not $extended Then _ArrayAdd($aResults, $path & $seek) EndIf EndIf EndIf EndIf EndIf WEnd FileClose($search) $aResults[0] = UBound($aResults) - 1 Return SetError(0, 0, $aResults) Else Return SetError(3) EndIf Else Return SetError(1) EndIf EndFunc Regards, UEZ Edited November 30, 2010 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
ZipleR Posted February 12, 2010 Share Posted February 12, 2010 UEZ: Thanks for the code... Unfortunately, I can not get this to work recurrsively... I did not want to run this against my entire c:\, so I created a c:\2 folder. In there I created Several Sub Folders, and Additional Sub Folders below that. When I run this script against the c:\2\ folder it only returns 1 file from the c:\2\ folder, and nothing else. (Should return 3 files from each folder) Problem is, I dont see in the code where the problem might be... ------------------------------------------------------------ Just figured it out. The Version of AutoIt I am using is 3.2.2.0... Somewhere between 3.2.2.0 and 3.3.2.0 the FileFindNext function changed and now sets @extended.. Thanks! (I could cancel the post, but maybe it will help others.) Link to comment Share on other sites More sharing options...
UEZ Posted February 12, 2010 Share Posted February 12, 2010 (edited) I just updated the code from post#10 because I had some bugs with the RegEx function Please test it again. Some examples are at the top of the code how to use it!Thanks,UEZPS: it is still beta and more testing is needed!!! Edited February 13, 2010 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
Chefito Posted February 13, 2010 Share Posted February 13, 2010 Here I leave a link to the AutoIt forum in Spanish with other functions.My link of the functionSaludos. 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