Reputation: 45922
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
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
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
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