0

I'm writing a python script to copy all Excel files in a tree of directories to another directory. Straightforward, right?

Well, for some reason shutil.copy (or copy2, or copyfile for that matter) don't do anything, not even spit out an error message. Any ideas?

def goFunc(self, event):
    print "Starting Go"
    for (path, dirs, files) in os.walk(self.path):
        print path
        print dirs
        print files
        for every_file in files:
            filename = str(path) + str(every_file)
            print filename
            if filename.endswith('.xlsx'):
                print "Copying " + filename + " to " + str(self.path2)
                shutil.copyfile(filename, str(self.path2))
    print "All DONE!"

So, I added a try except around the copying step, and it seems that it's that step that is the problem:

def goFunc(self, event):
    print "Starting Go"
    for (path, dirs, files) in os.walk(self.path):
        print path
        print dirs
        print files
        for every_file in files:
            filename = str(path) +'/' + str(every_file)
            print filename
            if filename.endswith('.xlsx'):
                print "Copying " + filename + " to " + str(self.path2)
                try:
                    shutil.copyfile(filename, str(self.path2))
                except:
                    print "Something went wrong"
                    pass
    print "All DONE!"

Now the output is:

Starting Go
/Users/laptop/Desktop
[u'test']
[u'.DS_Store', u'.localized', u'Maytag.xlsx', u'mer.xlsx']
/Users/laptop/Desktop/.DS_Store
/Users/laptop/Desktop/.localized
/Users/laptop/Desktop/Maytag.xlsx
Copying /Users/laptop/Desktop/Maytag.xlsx to /Users/laptop/test
Something went wrong
/Users/laptop/Desktop/mer.xlsx
Copying /Users/laptop/Desktop/mer.xlsx to /Users/laptop/test
Something went wrong
/Users/laptop/Desktop/test
[]
[]
All DONE!

The files still aren't being copied for some reason.

Solution:

Looks like I needed to add file names to the destinations. Now it works like a charm! Thanks everyone for yout time and help.

def goFunc(self, event):
    print "Starting Go"
    for (path, dirs, files) in os.walk(self.path):
        print path
        print dirs
        print files
        for every_file in files:
            filename = str(path) +'/' + str(every_file)
            print filename
            if filename.endswith('.xlsx'):
                print "Copying " + filename + " to " + str(self.path2) + '/' + str(every_file)
                try:
                    shutil.copyfile(filename, str(self.path2)+'/'+ str(every_file))
                except:
                    print "Something went wrong"
                    pass
print "All DONE!"
user1602004
  • 107
  • 1
  • 7
  • `filename` doesn't have a path separator in there... – Jon Clements Sep 28 '12 at 15:23
  • i was just about to post that I put that in, but it still isn't working – user1602004 Sep 28 '12 at 15:23
  • Is path2 changing for each of these files? If not, it will just keep overwriting whatever path2 is. copyfile wants a complete filename for dst. You could use shutil.copy if you want something that accepts a directory for the destination. – TimothyAWiseman Sep 28 '12 at 16:24

2 Answers2

1

You could (ab)use shutil.copytree

import shutil
import os.path

src = '/home/jon/Development/number5'
dst = '/home/jon/tmpso'

def not_xlsx(path, names):
    return {name for name in names if os.path.isfile(name) and not name.endswith('.xlsx')}

shutil.copytree(src, dst, ignore=not_xlsx)

You could also look at the fnmatch module if you wanted more complex wildcard/etc... matching (maybe something like):

def not_xlsx(path, names):
    actual_files = filter(os.path.isfile, names)
    return set(actual_files).difference(fnmatch.filter(actual_files, '*.xlsx'))
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
0

Using th os.walk method is good, but it also returns stuff like [] and ., so careful with it. Here is a class method that should would:

def goFunc(self, event):
    '''this should be enough to copy files that end with xlsx'''
    print "Starting Go"
    for file in os.listdir(Yourdir):
        if file.endswith('.xlsx'):
                print "Copying " + filename + " to " + str(self.path2)
                shutil.copyfile(filename, self.path2)
    print "All DONE!"

OK, don't reinvent the wheel:

dirs=[o for o in os.listdir(TopOfTree) if os.path.isdir(o)]
for dir in dirs:
    goFunc(event)

see here Getting a list of all subdirectories in the current directory

Community
  • 1
  • 1
oz123
  • 27,559
  • 27
  • 125
  • 187
  • The reason I used os.walk instead of os.listdir is that I wanted all the files in the file tree, rather than just that one directory. I guess I could write a recursive function that could do that for me, I just figured os.walk would be easier. – user1602004 Sep 28 '12 at 15:29
  • oh, sorry, that was not clear to me. Just filter out, that stuff like '[]' and '.', take a look of the output of os.walk. I think it might be the cause for your problem. – oz123 Sep 28 '12 at 15:31
  • I thought so too, but when I look at the output of my print statementsthey look fine: `Starting Go /Users/laptop/Desktop [u'test'] [u'.DS_Store', u'.localized', u'Maytag.xlsx', u'mer.xlsx'] /Users/laptop/Desktop/.DS_Store /Users/laptop/Desktop/.localized /Users/laptop/Desktop/Maytag.xlsx Copying /Users/laptop/Desktop/Maytag.xlsx to /Users/laptop/test` and then nothing happens – user1602004 Sep 28 '12 at 15:33
  • I just expanded how you can get a list of the sub directories, copy all the Excel files from them. – oz123 Sep 28 '12 at 15:37
  • It might be a problem with the file actually, see my self answer – user1602004 Sep 28 '12 at 15:41