Jump to content

Recommended Posts

Posted

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.

Posted

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.

Posted

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

  • Moderators
Posted (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 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!

Posted
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?

  • Moderators
Posted

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!

Posted
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??

Posted

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.

Posted
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?

Posted

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.

Posted

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.

Posted

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.

Posted

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.

Posted (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 by SadBunny

Roses are FF0000, violets are 0000FF... All my base are belong to you.

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...