Silver Light
Silver Light

Reputation: 45922

List all subdirectories on given level

I have backup directory structure like this (all directories are not empty):

/home/backups/mysql/
    2012/
        12/
           15/
    2013/
        04/
           29/
           30/
        05/
           02/
           03/
           04/
           05/

I want to get a list of all directories containing the backups, by providing only a root directory path:

get_all_backup_paths('/home/backups/mysql', level=3) 

This should return:

/home/backups/mysql/2012/12/15
/home/backups/mysql/2013/04/29
/home/backups/mysql/2013/04/30
/home/backups/mysql/2013/05/02
/home/backups/mysql/2013/05/03
/home/backups/mysql/2013/05/04
/home/backups/mysql/2013/05/05

And those should not be present in the result:

/home/backups/mysql/2012
/home/backups/mysql/2012/12
/home/backups/mysql/2013
/home/backups/mysql/2013/04
/home/backups/mysql/2013/05

Is there any way to os.listdir 3 levels down, excluding all the other levels? If yes, I would appriciate your help.

def get_all_backup_paths(dir, level):
    # ????

Upvotes: 2

Views: 2806

Answers (3)

John Smith Optional
John Smith Optional

Reputation: 24846

import functools, os

def deepdirs(directory, depth = 0):
    if depth == 0:
        return list(filter(os.path.isdir, [os.path.join(directory, d) for d in os.listdir(directory)]))
    else:
        return functools.reduce(list.__add__, [deepdirs(d) for d in deepdirs(directory, depth-1)], [])

Upvotes: 0

RichieHindle
RichieHindle

Reputation: 281485

You can use glob to search down a directory tree, like this:

import os, glob
def get_all_backup_paths(dir, level):
   pattern = dir + level * '/*'
   return [d for d in glob.glob(pattern) if os.path.isdir(d)]

I included a check for directories as well, in case there might be files mixed in with the directories.

Upvotes: 5

Fred Foo
Fred Foo

Reputation: 363587

from glob import iglob

level3 = iglob('/home/backups/mysql/*/*/*')

(This will skip "hidden" directories with names starting with .)

If there may be non-directories at level 3, skip them using:

from itertools import ifilter
import os.path

l3_dirs = ifilter(os.path.isdir, level3)

In Python 3, use filter instead of ifilter.

Upvotes: 10

Related Questions