Заставить os.walk работать нестандартно

Я пытаюсь сделать следующее, в этом порядке:

Используйте os.walk() для перехода вниз по каждому каталогу.
В каждом каталоге есть subfolders, но меня интересует только первый subfolder. Итак, каталог выглядит так:

/home/RawData/SubFolder1/SubFolder2

Например. Я хочу, чтобы в RawData2 были папки, которые останавливаются на уровне SubFolder1.

Дело в том, что кажется, что os.walk() проходит через ВСЮ папку RawData, и я не уверен, как это остановить.

Ниже приведено то, что у меня есть до сих пор - я пробовал несколько других комбинаций замены переменных каталогов на корень или файлы, но, похоже, это не дает мне того, что я хочу.

import os 

for root, dirs, files in os.walk("/home/RawData"): 

    os.chdir("/home/RawData2/")
    make_path("/home/RawData2/"+str(dirs))

person Z R    schedule 17.10.2015    source источник
comment
Не понятно, что ты имеешь в виду, можно подробнее?   -  person kasravnd    schedule 17.10.2015
comment
Ну, os.walk() проходит через все уровни RawData и связанные с ними подпапки. Я заинтересован в том, чтобы он спустился только на один уровень, а не на все сразу. Может быть, другая функция была бы более подходящей?   -  person Z R    schedule 17.10.2015
comment
Может быть, полезной альтернативой будет glob?   -  person swenzel    schedule 17.10.2015
comment
То есть вы имеете в виду, что у вас есть только путь к корню и имя этой подпапки, верно?   -  person kasravnd    schedule 17.10.2015
comment
Да, вместо того, чтобы сохранять всю структуру SubFolder1/SubFolder2/SubFolder3, ограничивая ее SubFolder1. В конце концов, я возьму все файлы из SubFolders1,2,3 и положу их в эту новую папку.   -  person Z R    schedule 17.10.2015


Ответы (2)


Я предлагаю вам вместо этого использовать glob.

Как описано в справке по glob:

glob(pathname)
    Return a list of paths matching a pathname pattern.

    The pattern may contain simple shell-style wildcards a la
    fnmatch. However, unlike fnmatch, filenames starting with a
    dot are special cases that are not matched by '*' and '?'
    patterns.

Итак, ваш шаблон — это каждый каталог первого уровня, который, думаю, будет выглядеть примерно так:

/root_path/*/sub_folder1/sub_folder2

Итак, вы начинаете со своего корня, получаете все на этом первом уровне, а затем ищете sub_folder1/sub_folder2. Думаю, это работает.

Чтобы собрать все вместе:

from glob import glob

dirs = glob('/root_path/*/sub_folder1/sub_folder2')

# Then iterate for each path
for i in dirs:
    print(i)
person idjaw    schedule 17.10.2015
comment
Дело в том, что мне нужно, чтобы sub_folder2 перебирал кучу разных папок. Я не уверен, что ваш метод сделает это. - person Z R; 17.10.2015
comment
Итак, вы говорите, что хотите просмотреть все подкаталоги отфильтрованного совпадения? Поэтому, если вы отфильтровали /root_path/*/sub1/sub2. Затем вы хотите взять каждый из них и повторить каждый из них для всего остального в этих путях? - person idjaw; 17.10.2015

Осторожно: в документации для os.walk говорится:

не меняйте текущий рабочий каталог между повторениями walk(). walk() никогда не изменяет текущий каталог и предполагает, что его вызывающая сторона также не

поэтому вам следует избегать os.chdir("/home/RawData2/") в цикле walk.

Вы можете легко попросить walk не использовать рекурсию, используя topdown=True и очистив dirs:

for root, dirs, files in os.walk("/home/RawData", True):
    for rep in dirs:
        make_path(os.join("/home/RawData2/", rep )
        # add processing here
    del dirs[]  # tell walk not to recurse in any sub directory
person Serge Ballesta    schedule 17.10.2015
comment
Я попробую это через мгновение. Отчитаюсь, как пойдет. - person Z R; 17.10.2015
comment
Что ж, это лучше, поскольку теперь он создает SubFolder1, но также создает все папки на уровне SubFolder2. - person Z R; 17.10.2015
comment
@ZR: я должен был это проверить. Список является изменяемым объектом, но l = [] не изменяет исходный список, а просто делает ссылку на пустой список. Должно быть del l[:]. Сообщение отредактировано - person Serge Ballesta; 18.10.2015