简体   繁体   中英

shutil.rmtree in mixed hierarchy levels in python

I'm a python newbie (so far, I'm only proficient in bash scripting) and I've got a question on recursion and shutil.rmtree .

So, I have the following snippet...

keepthese = ('dir1', 'dir2', '.dotfile1', '.dotfile2', 'dir3', '.dotdir1')
dirpath = '/home/' + username + '/parentdir/'
killthese = [os.path.join('/home', username, '/parentdir', item) for item in os.listdir(dirpath) if item not in keepthese]
for x in killthese:
    if os.path.isdir(x):
        shutil.rmtree(x)
    else:
        os.remove(x)

(yes, I know it doesn't seem very clean).

Essentially, I've got a set of filenames/directories. for this example, I'll be using dir1 .

Now, I have a directory layout that recurses in dir1 , there will also be another directory named dir1 , .dotdir , etc.

What I want to do is keep the first level of hierarchy (and obviously delete every file/directory in parentdir/ that does not match keepthese), but in every directory listed in keepthese, I want to remove everything (so I can't do a recursion based on name only, or else I'll delete the first level of keepthese iterates).

Does this make sense?

Assuming you want to:

  • remove everything in a given root directory, bar a list of excepted directories
  • remove everything within each excepted directory

Then something like this (untested!) script should work:

import sys, os, shutil

def prune(dirpath, exceptions=()):
    for name in os.listdir(dirpath):
        path = os.path.join(dirpath, name)
        if name in exceptions:
            prune(path)
        else:
            if os.path.isdir(path):
                shutil.rmtree(path)
            else:
                os.remove(path)

exceptions = ('dir1', 'dir2', '.dotfile1', '.dotfile2', 'dir3', '.dotdir1')

if __name__ == '__main__':

    root = os.path.join('/home', sys.argv[1], 'parentdir')

    prune(root, exceptions)

I'd try using os.walk with something like...

for root, dirs, files in os.walk(dirpath, topdown=False):
    for name in files:
        os.remove(os.path.join(root, name))
    for name in dirs:
        if name not in keepthese:
            os.rmdir(os.path.join(root, name))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM