os.walk ()를 사용하여 파이썬에서 디렉토리를 재귀 적으로 순회


151

루트 디렉토리에서 다른 모든 디렉토리로 이동하여 동일하게 인쇄하고 싶습니다.

내 코드는 다음과 같습니다.

#!/usr/bin/python

import os
import fnmatch

for root, dir, files in os.walk("."):
        print root
        print ""
        for items in fnmatch.filter(files, "*"):
                print "..." + items
        print ""

그리고 여기 내 O / P가 있습니다 :

.

...Python_Notes
...pypy.py
...pypy.py.save
...classdemo.py
....goutputstream-J9ZUXW
...latest.py
...pack.py
...classdemo.pyc
...Python_Notes~
...module-demo.py
...filetype.py

./packagedemo

...classdemo.py
...__init__.pyc
...__init__.py
...classdemo.pyc

이상은, ../packagedemo디렉토리입니다.

그러나 다음과 같은 방법으로 O / P를 인쇄해야합니다.

A
---a.txt
---b.txt
---B
------c.out

위, AB디렉토리이며, 나머지는 파일입니다.


6
나는 파이썬의 힘에 대해이 작은 글을 여기에 추가하고 싶다 : >>> print 2 * '
-'----

답변:


228

이것은 당신에게 원하는 결과를 줄 것입니다

#!/usr/bin/python

import os

# traverse root directory, and list directories as dirs and files as files
for root, dirs, files in os.walk("."):
    path = root.split(os.sep)
    print((len(path) - 1) * '---', os.path.basename(root))
    for file in files:
        print(len(path) * '---', file)

6
경로 = os.path.relpath (root, basepath) .split (os.sep)
Semprini

9
@Ajay는 편집증이며 os.walk(u".")경로는 유니 코드 일 수 있기 때문에 항상해야 합니다.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

3
더 나은,os.path.curdir
Jir

나는 오랫동안 사용 os.path.walk하고 있었기 때문에 os.walk나에게는 새로운 것이 아니다! 시원한 콩.
Tom

@Semprini basepath코드에서 동등한 것이 무엇 입니까?
stelios

23

이 시도:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""FileTreeMaker.py: ..."""

__author__  = "legendmohe"

import os
import argparse
import time

class FileTreeMaker(object):

    def _recurse(self, parent_path, file_list, prefix, output_buf, level):
        if len(file_list) == 0 \
            or (self.max_level != -1 and self.max_level <= level):
            return
        else:
            file_list.sort(key=lambda f: os.path.isfile(os.path.join(parent_path, f)))
            for idx, sub_path in enumerate(file_list):
                if any(exclude_name in sub_path for exclude_name in self.exn):
                    continue

                full_path = os.path.join(parent_path, sub_path)
                idc = "┣━"
                if idx == len(file_list) - 1:
                    idc = "┗━"

                if os.path.isdir(full_path) and sub_path not in self.exf:
                    output_buf.append("%s%s[%s]" % (prefix, idc, sub_path))
                    if len(file_list) > 1 and idx != len(file_list) - 1:
                        tmp_prefix = prefix + "┃  "
                    else:
                        tmp_prefix = prefix + "    "
                    self._recurse(full_path, os.listdir(full_path), tmp_prefix, output_buf, level + 1)
                elif os.path.isfile(full_path):
                    output_buf.append("%s%s%s" % (prefix, idc, sub_path))

    def make(self, args):
        self.root = args.root
        self.exf = args.exclude_folder
        self.exn = args.exclude_name
        self.max_level = args.max_level

        print("root:%s" % self.root)

        buf = []
        path_parts = self.root.rsplit(os.path.sep, 1)
        buf.append("[%s]" % (path_parts[-1],))
        self._recurse(self.root, os.listdir(self.root), "", buf, 0)

        output_str = "\n".join(buf)
        if len(args.output) != 0:
            with open(args.output, 'w') as of:
                of.write(output_str)
        return output_str

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-r", "--root", help="root of file tree", default=".")
    parser.add_argument("-o", "--output", help="output file name", default="")
    parser.add_argument("-xf", "--exclude_folder", nargs='*', help="exclude folder", default=[])
    parser.add_argument("-xn", "--exclude_name", nargs='*', help="exclude name", default=[])
    parser.add_argument("-m", "--max_level", help="max level",
                        type=int, default=-1)
    args = parser.parse_args()
    print(FileTreeMaker().make(args))

당신은 이것을 얻을 것입니다 :

root:.
[.]
┣━[.idea]
  ┣━[scopes]
    ┗━scope_settings.xml
  ┣━.name
  ┣━Demo.iml
  ┣━encodings.xml
  ┣━misc.xml
  ┣━modules.xml
  ┣━vcs.xml
  ┗━workspace.xml
┣━[test1]
  ┗━test1.txt
┣━[test2]
  ┣━[test2-2]
    ┗━[test2-3]
        ┣━test2
        ┗━test2-3-1
  ┗━test2
┣━folder_tree_maker.py
┗━tree.py

안녕하세요. 저는 스크립트를 정말 좋아하지만 작업중 인 프로젝트에는 너무 복잡합니다 .-r 인수 만 있으면 하나의 작은 함수로 사용할 수 있습니까?
jeff_h 2012 년

.txt로 인쇄하는 방법? 시도 print(FileTreeMaker().make(args),file=tree)했지만 그것은 나를 제공합니다'charmap' codec can't encode characters in position 17-21: character maps to <undefined>
Luis Felipe

IDC의 약자
음성

나도 비슷한 것을 썼다 os.listdir(). 당신이 훨씬 낫습니다. 나는 재귀를 올바르게 얻을 수 없었으며 2 ~ 3 층 깊이에서만 작동했습니다. 결국 나는 os.walk()대신에 처음부터 다시 시도하기로 결정 했는데 훨씬 더 적합 할 것이라고 생각했다. 나는 당신이 그것을 전혀 사용하지 않은 것에 놀랐습니다.
목소리

11

os패키지에 더 적합한 기능이 있습니다. 하지만 당신이 사용해야한다면 os.walk, 여기에 내가 생각해 낸 것이 있습니다.

def walkdir(dirname):
    for cur, _dirs, files in os.walk(dirname):
        pref = ''
        head, tail = os.path.split(cur)
        while head:
            pref += '---'
            head, _tail = os.path.split(head)
        print(pref+tail)
        for f in files:
            print(pref+'---'+f)

산출:

>>> walkdir('.')
.
---file3
---file2
---my.py
---file1
---A
------file2
------file1
---B
------file3
------file2
------file4
------file1
---__pycache__
------my.cpython-33.pyc

5
더 적합한 기능은 무엇입니까? (중요한 경우 3.5)
Al Lelopath

미안, 내가 무슨 뜻인지 기억할 기회가 없어 내가 의미 할 수도 os.listdir있지만 @ ajay의 솔루션이 그것을 능가합니다.
zaquest

5

을 사용할 수 있으며 os.walk아마도 가장 쉬운 솔루션 일지 모르지만 여기에 또 다른 아이디어가 있습니다.

import sys, os

FILES = False

def main():
    if len(sys.argv) > 2 and sys.argv[2].upper() == '/F':
        global FILES; FILES = True
    try:
        tree(sys.argv[1])
    except:
        print('Usage: {} <directory>'.format(os.path.basename(sys.argv[0])))

def tree(path):
    path = os.path.abspath(path)
    dirs, files = listdir(path)[:2]
    print(path)
    walk(path, dirs, files)
    if not dirs:
        print('No subfolders exist')

def walk(root, dirs, files, prefix=''):
    if FILES and files:
        file_prefix = prefix + ('|' if dirs else ' ') + '   '
        for name in files:
            print(file_prefix + name)
        print(file_prefix)
    dir_prefix, walk_prefix = prefix + '+---', prefix + '|   '
    for pos, neg, name in enumerate2(dirs):
        if neg == -1:
            dir_prefix, walk_prefix = prefix + '\\---', prefix + '    '
        print(dir_prefix + name)
        path = os.path.join(root, name)
        try:
            dirs, files = listdir(path)[:2]
        except:
            pass
        else:
            walk(path, dirs, files, walk_prefix)

def listdir(path):
    dirs, files, links = [], [], []
    for name in os.listdir(path):
        path_name = os.path.join(path, name)
        if os.path.isdir(path_name):
            dirs.append(name)
        elif os.path.isfile(path_name):
            files.append(name)
        elif os.path.islink(path_name):
            links.append(name)
    return dirs, files, links

def enumerate2(sequence):
    length = len(sequence)
    for count, value in enumerate(sequence):
        yield count, count - length, value

if __name__ == '__main__':
    main()

Windows 터미널의 TREE 명령에서 다음 문서를 인식 할 수 있습니다.

Graphically displays the folder structure of a drive or path.

TREE [drive:][path] [/F] [/A]

   /F   Display the names of the files in each folder.
   /A   Use ASCII instead of extended characters.

5

위의 코드에는 단순성이 없기 때문에 현재 디렉토리의 모든 디렉토리에서 모든 파일을 가져오고 현재 디렉토리에서 모든 디렉토리를 얻는 디렉토리를 재귀 적으로 살펴보십시오.

for root, dirs, files in os.walk(rootFolderPath):
    for filename in files:
        doSomethingWithFile(os.path.join(root, filename))
    for dirname in dirs:
        doSomewthingWithDir(os.path.join(root, dirname))

3
가장 유용한 답변. 참고 os.path.join(root, filename)파일이 여러 디렉토리에 중첩 된 경우에도 해당 파일의 전체 경로를 제공합니다.
clw

4

이것은 폴더 이름에 대해 수행됩니다.

def printFolderName(init_indent, rootFolder):
    fname = rootFolder.split(os.sep)[-1]
    root_levels = rootFolder.count(os.sep)
    # os.walk treats dirs breadth-first, but files depth-first (go figure)
    for root, dirs, files in os.walk(rootFolder):
        # print the directories below the root
        levels = root.count(os.sep) - root_levels
        indent = ' '*(levels*2)
        print init_indent + indent + root.split(os.sep)[-1]

3
#!/usr/bin/python

import os 

def tracing(a):
    global i>
    for item in os.listdir(a):
        if os.path.isfile(item):
            print i + item 
        else:
            print i + item 
            i+=i
            tracing(item)

i = "---"
tracing(".")

1

폴더 이름이 주어지면 전체 계층 구조를 재귀 적으로 살펴보십시오.

#! /usr/local/bin/python3
# findLargeFiles.py - given a folder name, walk through its entire hierarchy
#                   - print folders and files within each folder

import os

def recursive_walk(folder):
    for folderName, subfolders, filenames in os.walk(folder):
        if subfolders:
            for subfolder in subfolders:
                recursive_walk(subfolder)
        print('\nFolder: ' + folderName + '\n')
        for filename in filenames:
            print(filename + '\n')

recursive_walk('/name/of/folder')

4
이미 재귀를 평평하게하므로 os.walk를 재귀 적으로 호출 할 필요가 없습니다. 이것이 folderName 인수를 반환하는 이유입니다.
gwideman

1

가장 좋은 방법이 될 것입니다

def traverse_dir_recur(dir):
    import os
    l = os.listdir(dir)
    for d in l:
        if os.path.isdir(dir + d):
            traverse_dir_recur(dir+  d +"/")
        else:
            print(dir + d)

Python3에서 나를 위해 작동하지 않습니다. 오류가에 있다고 가정하면 dir + d디렉토리 구분 기호없이 오류가 발생할 수 있습니다. os.path.join파일 이름이있는 디렉토리 를 연결하는 데 사용 하는 것이 좋습니다.
Zvika

0

이것을 시도하십시오; 쉬운 것

 #!/usr/bin/python
 import os
 # Creating an empty list that will contain the already traversed paths
 donePaths = []
 def direct(path):
       for paths,dirs,files in os.walk(path):
             if paths not in donePaths:
                    count = paths.count('/')
                    if files:
                          for ele1 in files:
                                print '---------' * (count), ele1
                    if dirs:
                          for ele2 in dirs:
                                print '---------' * (count), ele2
                                absPath = os.path.join(paths,ele2)
              # recursively calling the direct function on each directory
                                direct(absPath)
                   # adding the paths to the list that got traversed 
                                donePaths.append(absPath)

 path = raw_input("Enter any path to get the following Dir Tree ...\n")
 direct(path)

======== OUTPUT 이하 ========

 /home/test
 ------------------ b.txt
 ------------------ a.txt
 ------------------ a
 --------------------------- a1.txt
 ------------------ b
 --------------------------- b1.txt
 --------------------------- b2.txt
 --------------------------- cde
 ------------------------------------ cde.txt
 ------------------------------------ cdeDir
 --------------------------------------------- cdeDir.txt
 ------------------ c
 --------------------------- c.txt
 --------------------------- c1
 ------------------------------------ c1.txt
 ------------------------------------ c2.txt

이미 통과 한 경로를 확인하는 요점은 무엇입니까? 링크로 인한 루프를 감지하려면 os.walk는 기본적으로 링크를 따르지 않는 것으로 보입니다. 다른 상황이 있습니까?
gwideman

0

이 시도:

import os
root_name = next(os.walk("."))[0]
dir_names = next(os.walk("."))[1]
file_names = next(os.walk("."))[2]

여기서 나는 당신의 길을 "."라고 가정합니다. root_file과 다른 디렉토리가 있습니다. 따라서 기본적으로 os.walk는 생성 함수이므로 next () 호출을 사용하여 트리 전체에서 반복합니다. 이렇게하면 모든 디렉토리 및 파일 이름을 각각 dir_names 및 file_names에 저장할 수 있습니다.


0

pathlib.Path ()를 사용하여 재귀 적으로 폴더를 탐색 하고 모든 내용을 나열 할 수 있습니다

from pathlib import Path


def check_out_path(target_path, level=0):
    """"
    This function recursively prints all contents of a pathlib.Path object
    """
    def print_indented(folder, level):
        print('\t' * level + folder)

    print_indented(target_path.name, level)
    for file in target_path.iterdir():
        if file.is_dir():
            check_out_path(file, level+1)
        else:
            print_indented(file.name, level+1)


my_path = Path(r'C:\example folder')
check_out_path(my_path)

산출:

example folder
    folder
        textfile3.txt
    textfile1.txt
    textfile2.txt

-3
import os

os.chdir('/your/working/path/')
dir = os.getcwd()
list = sorted(os.listdir(dir))
marks = ""

for s_list in list:
    print marks + s_list
    marks += "---"
    tree_list = sorted(os.listdir(dir + "/" + s_list))
    for i in tree_list:
        print marks + i

나무 전체를 가로 지르는 것처럼 보이지 않습니다.
모든 근로자가 필수적
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.