VPeric
VPeric

Reputation: 7461

Copying files recursively with skipping some directories in Python?

I want to copy a directory to another directory recursively. I also want to ignore some files (eg. all hidden files; everything starting with ".") and then run a function on all the other files (after copying them). This is simple to do in the shell, but I need a Python script.

I tried using shutil.copytree, which has ignore support, but I don't know how to have it do a function on each file copied. I might also need to check some other condition when copying so I can't just run the function on all the files once they are copied over. I also tried looking at os.walk but I couldn't figure it out.

Upvotes: 3

Views: 2446

Answers (2)

GaretJax
GaretJax

Reputation: 7780

You can use os.walk to iterate over each file, apply your custom filtering function and copying over only the ones you care.

os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])

Generate the file names in a directory tree by walking the tree either top-down or bottom-up. For each directory in the tree rooted at directory top (including top itself), it yields a 3-tuple (dirpath, dirnames, filenames).

You can add all copied files to a list and use it to run you custom script or run the script after each copy operation.

This should get you started:

import os

def filterls(src, filter_func):
    for root, dirs, files in os.walk(src):
        for f in files:
            if filter_func(f):
                path = os.path.join(root, f)
                yield path[len(src)+1:]

It takes a path to a directory and a function which takes a single parameter. If the function returns False for the passed filename, the file is ignored.

You can try it in a python interpreter like this:

# Get a list of all visible files rooted in the 'path/to/the/dir' directory
print list(filterls('path/to/the/dir', lambda p: not p.startswith('.')))

Upvotes: 7

pyroscope
pyroscope

Reputation: 4158

If you're on Python 2.6 or higher, you can simply use shutil.copytree and its ignore argument. Since it gets passed all the files and directories, you can call your function from there, unless you want it to be called right after the file is copied.

If that is the case, the easiest thing is to copy and modify the copytree code.

Upvotes: 4

Related Questions