打印出整个目录树

Posted

技术标签:

【中文标题】打印出整个目录树【英文标题】:Print out the whole directory tree 【发布时间】:2013-07-08 17:17:54 【问题描述】:

我现在的代码:

import os

Tree = 
Tree = os.listdir('Dir')
>>> print(Tree)
['New Folder', 'Textfile1.txt', 'Textfile2.txt']

这不会打印出子目录中的文件。 (新建文件夹是一个子目录)。

我的问题是,如何输出目录下的所有文件和子目录下的文件?

【问题讨论】:

阅读文档并了解 os.walk 的工作原理。 【参考方案1】:

Here 是另一个适用于 python3 的版本

示例输出:

pyvarstar/
|-- .bashrc
|-- README
|-- vstars -> versions/vstars_20170804/ 
|-- versions/ 
|   |-- vstars_20170804/ 
|   |   |-- lib/
|   |   |   |-- vstars/ 
|   |   |-- bin/ 
|   |   |   |-- getcoords
|   |   |   |-- find_burst

代码:

def realname(path, root=None):
    if root is not None:
        path=os.path.join(root, path)
    result=os.path.basename(path)
    if os.path.islink(path):
        realpath=os.readlink(path)
        result= '%s -> %s' % (os.path.basename(path), realpath)
    return result

def ptree(startpath, depth=-1):
    prefix=0
    if startpath != '/':
        if startpath.endswith('/'): startpath=startpath[:-1]
        prefix=len(startpath)
    for root, dirs, files in os.walk(startpath):
        level = root[prefix:].count(os.sep)
        if depth >-1 and level > depth: continue
        indent=subindent =''
        if level > 0:
            indent = '|   ' * (level-1) + '|-- '
        subindent = '|   ' * (level) + '|-- '
        print('/'.format(indent, realname(root)))
        # print dir only if symbolic link; otherwise, will be printed as root
        for d in dirs:
            if os.path.islink(os.path.join(root, d)):
                print(''.format(subindent, realname(d, root=root)))
        for f in files:
            print(''.format(subindent, realname(f, root=root)))

【讨论】:

【参考方案2】:

从Python Cookbook 上的recipe 577091,您可以使用或学习那里的TREE Emulator

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()

【讨论】:

【参考方案3】:
import os 
def Test1(rootDir): 
    list_dirs = os.walk(rootDir) 
    for root, dirs, files in list_dirs: 
        for d in dirs: 
            print os.path.join(root, d)      
        for f in files: 
            print os.path.join(root, f) 

或者:

import os 
def Test2(rootDir): 
    for lists in os.listdir(rootDir): 
        path = os.path.join(rootDir, lists) 
        print path 
        if os.path.isdir(path): 
            Test2(path)

对于测试文件树:

E:\TEST 
│--A 
│  │--A-A 
│  │  │--A-A-A.txt 
│  │--A-B.txt 
│  │--A-C 
│  │  │--A-B-A.txt 
│  │--A-D.txt 
│--B.txt 
│--C 
│  │--C-A.txt 
│  │--C-B.txt 
│--D.txt 
│--E 

运行以下代码:

Test1('E:\TEST') 
print '=======================================' 
Test2('E:\TEST') 

您可以看到结果之间存在差异:

>>>  
E:\TEST\A 
E:\TEST\C 
E:\TEST\E 
E:\TEST\B.txt 
E:\TEST\D.txt 
E:\TEST\A\A-A 
E:\TEST\A\A-C 
E:\TEST\A\A-B.txt 
E:\TEST\A\A-D.txt 
E:\TEST\A\A-A\A-A-A.txt 
E:\TEST\A\A-C\A-B-A.txt 
E:\TEST\C\C-A.txt 
E:\TEST\C\C-B.txt 
======================================= 
E:\TEST\A 
E:\TEST\A\A-A 
E:\TEST\A\A-A\A-A-A.txt 
E:\TEST\A\A-B.txt 
E:\TEST\A\A-C 
E:\TEST\A\A-C\A-B-A.txt 
E:\TEST\A\A-D.txt 
E:\TEST\B.txt 
E:\TEST\C 
E:\TEST\C\C-A.txt 
E:\TEST\C\C-B.txt 
E:\TEST\D.txt 
E:\TEST\E 
>>> 

要将它们保存在列表中:

import os 
files = []
def Test1(rootDir):
    files.append(rootDir)
    list_dirs = os.walk(rootDir) 
    for root, dirs, files in list_dirs: 
        for d in dirs: 
            files.append(os.path.join(root, d))      
        for f in files: 
            files.append(os.path.join(root, f))

import os 
files = [rootDir]
def Test2(rootDir):
    for lists in os.listdir(rootDir): 
        path = os.path.join(rootDir, lists) 
        files.append(path) 
        if os.path.isdir(path): 
            Test2(path)

【讨论】:

你能不能让它不打印值而是将它们作为列表返回? 所以你只想要文件或文件和目录? @HendrX【参考方案4】:

使用os.walk:

>>> import os
>>> print(os.walk.__doc__)
Directory tree generator.

    For each directory in the directory tree rooted at top (including top
    itself, but excluding '.' and '..'), yields a 3-tuple
    ...

【讨论】:

以上是关于打印出整个目录树的主要内容,如果未能解决你的问题,请参考以下文章

遍历整个目录树的文件和目录

遍历整个目录树的文件和目录

在c#中遍历对象树

svn稀疏目录--通过设置工作目录的深度(depth)实现目录树的部分签出

使用IO,递归打印目录树

windows下使用tree工具打印目录树