Sarah2016 Posted November 28, 2016 Share Posted November 28, 2016 Hi ! I am new to AutoIt and this is my first post ! I need a help in accomplishing the following: I have a folder containing many subfolders. Inside them many different files. I want to copy all *.doc and *.docx files using autoit into a new folder. Your help is appreciated. Link to comment Share on other sites More sharing options...
SadBunny Posted November 28, 2016 Share Posted November 28, 2016 Questions: 1) Do you want to retain the original directory structure? 2) Have you used the search function and/or Google? This has been done before What have you tried? 3) Are you sure you need (or want to use) AutoIt? A quick robocopy (robocopy <source-dir> <destination-dir> *.doc *.docx /s) or a nice Powershell oneliner seems easier. If you want to use AutoIt, check out _FileListToArrayRec and FileCopy. Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
Sarah2016 Posted November 28, 2016 Author Share Posted November 28, 2016 Prompt response. Thanks! 1. Not necesssary, but in case of I didn't retain the original directory structure and I got duplicated, this is the only problem. 2. I did but didn't get what I wanted. 3. Using another tool does not suit my need because will using that code in a loop. Thanks Link to comment Share on other sites More sharing options...
Moderators JLogan3o13 Posted November 28, 2016 Moderators Share Posted November 28, 2016 (edited) @Sarah2016 something like this perhaps: #include <File.au3> Local $aFolders = _FileListToArrayRec(@ScriptDir & "\1", "*", $FLTAR_FOLDERS, $FLTAR_RECUR, $FLTAR_SORT, $FLTAR_FULLPATH) For $a = 1 To $aFolders[0] FileCopy($aFolders[$a] & "\*.docx", @TempDir & "\*.docx", 1) Next assuming my file structure is 1 (top level), 2,3,4 all subfolders of one. This will pull any .docx file from any of them and put it into the temp directory. I suggest looking into both the _FileListToArrayRec and FileCopy subjects in the help file and trying to modify this to fit your needs. Feel free to ask questions if you run into issues. Edit: Welcome to the forum, btw Edited November 28, 2016 by JLogan3o13 "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum! Link to comment Share on other sites More sharing options...
Sarah2016 Posted November 28, 2016 Author Share Posted November 28, 2016 8 minutes ago, JLogan3o13 said: @Sarah2016 something like this perhaps: #include <File.au3> Local $aFolders = _FileListToArrayRec(@ScriptDir & "\1", "*", $FLTAR_FOLDERS, $FLTAR_RECUR, $FLTAR_SORT, $FLTAR_FULLPATH) For $a = 1 To $aFolders[0] FileCopy($aFolders[$a] & "\*.docx", @TempDir & "\*.docx", 1) Next assuming my file structure is 1 (top level), 2,3,4 all subfolders of one. This will pull any .docx file from any of them and put it into the temp directory. I suggest looking into both the _FileListToArrayRec and FileCopy subjects in the help file and trying to modify this to fit your needs. Feel free to ask questions if you run into issues. Edit: Welcome to the forum, btw Fantastic! 1 problem: this code only copies .docx files, how to include .doc as well? Link to comment Share on other sites More sharing options...
Moderators JLogan3o13 Posted November 28, 2016 Moderators Share Posted November 28, 2016 Look at the remarks under FileCopy. You should be able to wildcard the extension, something like this: FileCopy($aFolders[$a] & "\*.doc*", @TempDir, 1) "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum! Link to comment Share on other sites More sharing options...
Sarah2016 Posted November 28, 2016 Author Share Posted November 28, 2016 10 minutes ago, JLogan3o13 said: Look at the remarks under FileCopy. You should be able to wildcard the extension, something like this: FileCopy($aFolders[$a] & "\*.doc*", @TempDir, 1) I know that.. but I want to use different method.. because that does not work if I want to copy doc and ppt for example?? Link to comment Share on other sites More sharing options...
SadBunny Posted November 28, 2016 Share Posted November 28, 2016 The easiest solution would be to simply repeat the FileCopy with different filespecs. One could also consider specifying the second parameter in the _FileListToArrayRec function call (the $sMask), as it allows multiple filters separated by ; Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
Sarah2016 Posted November 28, 2016 Author Share Posted November 28, 2016 21 minutes ago, SadBunny said: The easiest solution would be to simply repeat the FileCopy with different filespecs. One could also consider specifying the second parameter in the _FileListToArrayRec function call (the $sMask), as it allows multiple filters separated by ; thanks, but the second option you mentioned does not seem to work because the _filelisttoarrayrec will retrieve FOLDERS list not files.. Am I right? Link to comment Share on other sites More sharing options...
SadBunny Posted November 28, 2016 Share Posted November 28, 2016 Have you read the help file for _FileListToArrayRec? (I know it's not the easiest command to understand if you're writing your first script, but the help file is very informative ) Read the bit about $iReturn - you can specify whether to return a list of files, a list of folders or a list of both files and folders. Change the $FLTAR_FOLDERS in Logan's example to $FLTAR_FILES or $FLTAR_FILESFOLDERS and it will return the respective information. Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
SadBunny Posted November 28, 2016 Share Posted November 28, 2016 I created a test dir: Quote c:\tmp\test>dir /s /b c:\tmp\test\1 c:\tmp\test\2 c:\tmp\test\3 c:\tmp\test\1\x.docx c:\tmp\test\1\y.doc c:\tmp\test\2\x.txt c:\tmp\test\2\y.doc And here's another example snippet: #include <File.au3> Local $aFolders = _FileListToArrayRec("c:\tmp\test", "*.doc;*.docx", $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_SORT, $FLTAR_FULLPATH) For $a = 1 To $aFolders[0] ConsoleWrite($aFolders[$a] & @CRLF) Next The console outputs: Quote c:\tmp\test\1\x.docx c:\tmp\test\1\y.doc c:\tmp\test\2\y.doc Hope this helps. Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
Sarah2016 Posted November 28, 2016 Author Share Posted November 28, 2016 you guys are amazing! thanks a lot Link to comment Share on other sites More sharing options...
SadBunny Posted November 28, 2016 Share Posted November 28, 2016 We know. We'll be here all night to sign our books, feel free to come up and say hi. kylomas 1 Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
Sarah2016 Posted November 29, 2016 Author Share Posted November 29, 2016 I got error: subsscript used on non-accessible variable when the array is empty ... what to do? thanks Link to comment Share on other sites More sharing options...
SadBunny Posted November 29, 2016 Share Posted November 29, 2016 It means that you're trying to retrieve an element from the array that it does not contain. If the array is empty, it contains no elements, so any element you would try to retrieve will lead to that error. If you know it's empty, why are you trying to get something from it? Compare it to opening your fridge, seeing it's empty, and still sticking your hand in there expecting to grab milk Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
Sarah2016 Posted November 29, 2016 Author Share Posted November 29, 2016 i fully understand that, my question is how to prevent this error (i.e. i don't want the program to exist due to error) Link to comment Share on other sites More sharing options...
SadBunny Posted November 29, 2016 Share Posted November 29, 2016 Well, the way to prevent the error is simple: don't try and access an element that does not exist. (Not trying to be pedantic - it's actually the solution ) You can tell how many elements an array contains by using UBound($myArray). You can tell whether a variable is an array in the first place by IsArray($myArray). So you have to write your script to be smart enough not to access an element that does not exist, and to not address a variable as an array if it's not an array. Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
SadBunny Posted November 29, 2016 Share Posted November 29, 2016 (edited) I asked a question earlier: "If you know it's empty, why are you trying to get something from it?" That was a serious question. If you know the array is empty, you also know that there's no element to retrieve, so if you try it anyway, you are doing it wrong. You have to make your script check the array to see whether the element you need actually exist, or alternatively make it understand in which situations looking up the array makes no sense. A good example of this is when a function returns an array, except when there's an error. Like StringRegExp. #include <Array.au3> handleThis(go("[abc")) ; broken pattern - StringRegExp will return 0 (instead of an array) and will set @error handleThis(go("(\w+)")) ; valid pattern - StringRegExp will return 5 matches handleThis(go("thisWillNotBeFound")) ; valid pattern - StringRegExp will lead to 0 matches, i.e. an empty array Func handleThis($aResult) If @error Then ; something went wrong, so let's not try and address the result as an array MsgBox(16, 0, "error") Else ; no error occured, so we can assume it's an array. MsgBox(64, 0, "The array contains " & UBound($aResult) & " elements.") _ArrayDisplay($aResult) ; If we would blindly assume the array has a third element, we would get an error when that assumption ; ... turns out false. So if we're interested in a third element BUT want to be safe against errors, ; ... we should first check whether that third element is actually available. If UBound($aResult) >= 3 Then ; (at least) 3 array elements exist, i.e. index 0, index 1 and index 2 $thirdElement = $aResult[2] MsgBox(64, 0, "There is a third element: " & $aResult[2]) EndIf EndIf EndFunc ;==>handleThis Func go($pattern) Return StringRegExp("hello I am Sad Bunny", $pattern, $STR_REGEXPARRAYGLOBALMATCH) EndFunc ;==>go Hope this helps. Edited November 29, 2016 by SadBunny Roses are FF0000, violets are 0000FF... All my base are belong to you. 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