Directory-tree listing in Python
如何在Python中获取给定目录中所有文件(和目录)的列表?
这是一种遍历目录树中每个文件和目录的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import os for dirname, dirnames, filenames in os.walk('.'): # print path to all subdirectories first. for subdirname in dirnames: print(os.path.join(dirname, subdirname)) # print path to all filenames. for filename in filenames: print(os.path.join(dirname, filename)) # Advanced usage: # editing the 'dirnames' list will stop os.walk() from recursing into there. if '.git' in dirnames: # don't go into any .git directories. dirnames.remove('.git') |
你可以使用
1 | os.listdir(path) |
有关参考和更多操作系统功能,请参阅以下内容:
- python 2文档:https://docs.python.org/2/library/os.html os.listdir
- python 3文档:https://docs.python.org/3/library/os.html os.listdir
下面是我经常使用的一个助手函数:
1 2 3 4 | import os def listdir_fullpath(d): return [os.path.join(d, f) for f in os.listdir(d)] |
1 2 3 4 | import os for filename in os.listdir("C:\\temp"): print filename |
如果你需要全局能力,也有一个模块。例如:
1 2 | import glob glob.glob('./[0-9].*') |
将返回如下内容:
1 | ['./1.gif', './2.txt'] |
请参阅此处的文档。
试试这个:
1 2 3 4 | import os for top, dirs, files in os.walk('./'): for nm in files: print os.path.join(top, nm) |
对于当前工作目录中的文件,不指定路径
Python 2.7:
1 2 | import os os.listdir(os.getcwd()) |
Python 3 .x:
1 2 | import os os.listdir() |
感谢StamKaly对python 3.x的评论
递归实现
1 2 3 4 5 6 7 8 9 | import os def scan_dir(dir): for name in os.listdir(dir): path = os.path.join(dir, name) if os.path.isfile(path): print path else: scan_dir(path) |
我写了一个很长的版本,有我可能需要的所有选项:http://sam.nipl.net/code/python/find.py
我想它也适合这里:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #!/usr/bin/env python import os import sys def ls(dir, hidden=False, relative=True): nodes = [] for nm in os.listdir(dir): if not hidden and nm.startswith('.'): continue if not relative: nm = os.path.join(dir, nm) nodes.append(nm) nodes.sort() return nodes def find(root, files=True, dirs=False, hidden=False, relative=True, topdown=True): root = os.path.join(root, '') # add slash if not there for parent, ldirs, lfiles in os.walk(root, topdown=topdown): if relative: parent = parent[len(root):] if dirs and parent: yield os.path.join(parent, '') if not hidden: lfiles = [nm for nm in lfiles if not nm.startswith('.')] ldirs[:] = [nm for nm in ldirs if not nm.startswith('.')] # in place if files: lfiles.sort() for nm in lfiles: nm = os.path.join(parent, nm) yield nm def test(root): print"* directory listing, with hidden files:" print ls(root, hidden=True) print"* recursive listing, with dirs, but no hidden files:" for f in find(root, dirs=True): print f if __name__ =="__main__": test(*sys.argv[1:]) |
一个很好的一行程序,只以递归方式列出文件。我在setup.py包的数据指令中使用了这个:
1 2 3 | import os [os.path.join(x[0],y) for x in os.walk('<some_directory>') for y in x[2]] |
我知道这不是问题的答案,但可能有用
对于Python 2
1 2 3 4 5 6 | #!/bin/python2 import os def scan_dir(path): print map(os.path.abspath, os.listdir(pwd)) |
对于Python 3
对于筛选和映射,您需要用list()将它们包装起来。
1 2 3 4 5 6 | #!/bin/python3 import os def scan_dir(path): print(list(map(os.path.abspath, os.listdir(pwd)))) |
现在的建议是用生成器表达式或列表理解替换map和filter的用法:
1 2 3 4 5 6 | #!/bin/python import os def scan_dir(path): print([os.path.abspath(f) for f in os.listdir(path)]) |
这里有一个单线的Python版本:
1 2 3 | import os dir = 'given_directory_name' filenames = [os.path.join(os.path.dirname(os.path.abspath(__file__)),dir,i) for i in os.listdir(dir)] |
此代码列出给定目录名中所有文件和目录的完整路径。
虽然
要列出目录内容,请构造一个路径对象并获取迭代器:
1 2 | In [16]: Path('/etc').iterdir() Out[16]: <generator object Path.iterdir at 0x110853fc0> |
如果我们只想要一张物品名称列表:
1 2 3 4 5 | In [17]: [x.name for x in Path('/etc').iterdir()] Out[17]: ['emond.d', 'ntp-restrict.conf', 'periodic', |
如果你只想要脏衣服:
1 2 3 4 5 | In [18]: [x.name for x in Path('/etc').iterdir() if x.is_dir()] Out[18]: ['emond.d', 'periodic', 'mach_init.d', |
如果需要该树中所有conf文件的名称:
1 2 3 4 5 | In [20]: [x.name for x in Path('/etc').glob('**/*.conf')] Out[20]: ['ntp-restrict.conf', 'dnsextd.conf', 'syslog.conf', |
如果要在树中列出大于等于1K的conf文件:
1 2 3 4 5 | In [23]: [x.name for x in Path('/etc').glob('**/*.conf') if x.stat().st_size > 1024] Out[23]: ['dnsextd.conf', 'pf.conf', 'autofs.conf', |
解析相对路径变得容易:
1 2 | In [32]: Path('../Operational Metrics.md').resolve() Out[32]: PosixPath('/Users/starver/code/xxxx/Operational Metrics.md') |
使用路径导航非常清楚(尽管意外):
1 2 3 4 5 6 7 8 9 | In [10]: p = Path('.') In [11]: core = p / 'web' / 'core' In [13]: [x for x in core.iterdir() if x.is_file()] Out[13]: [PosixPath('web/core/metrics.py'), PosixPath('web/core/services.py'), PosixPath('web/core/querysets.py'), |
如果我想我会把这个扔进去。简单而肮脏的通配符搜索方法。
1 2 3 4 | import re import os [a for a in os.listdir(".") if re.search("^.*\.py$",a)] |
供我添加扩展名或扩展文件的筛选器导入操作系统
1 2 3 4 5 6 7 8 9 10 | path = '.' for dirname, dirnames, filenames in os.walk(path): # print path to all filenames with extension py. for filename in filenames: fname_path = os.path.join(dirname, filename) fext = os.path.splitext(fname_path)[1] if fext == '.py': print fname_path else: continue |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #import modules import os _CURRENT_DIR = '.' def rec_tree_traverse(curr_dir, indent): "recurcive function to traverse the directory" #print"[traverse_tree]" try : dfList = [os.path.join(curr_dir, f_or_d) for f_or_d in os.listdir(curr_dir)] except: print"wrong path name/directory name" return for file_or_dir in dfList: if os.path.isdir(file_or_dir): #print"dir :", print indent, file_or_dir,"\" rec_tree_traverse(file_or_dir, indent*2) if os.path.isfile(file_or_dir): #print"file :", print indent, file_or_dir #end if for loop #end of traverse_tree() def main(): base_dir = _CURRENT_DIR rec_tree_traverse(base_dir,"") raw_input("enter any key to exit....") #end of main() if __name__ == '__main__': main() |
下面的代码将列出目录和目录中的文件
1 2 3 4 5 6 7 8 | def print_directory_contents(sPath): import os for sChild in os.listdir(sPath): sChildPath = os.path.join(sPath,sChild) if os.path.isdir(sChildPath): print_directory_contents(sChildPath) else: print(sChildPath) |
我知道这是个老问题。这是一个很好的方法,如果你在一台柳丝机上。
1 2 | import subprocess print(subprocess.check_output(["ls","/"]).decode("utf8")) |
和我一起工作的是上面saleh答案的一种修改版本。
代码如下:
"dir='给定的目录名'filenames=[os.path.abspath(os.path.join(dir,i)),用于os.listdir(dir)]
这是另一个选择。
1 | os.scandir(path='.') |
它返回与路径给定目录中的条目(连同文件属性信息)对应的os.direntry对象的迭代器。
例子:
1 2 3 4 | with os.scandir(path) as it: for entry in it: if not entry.name.startswith('.'): print(entry.name) |
使用scandir()而不是listdir()可以显著提高还需要文件类型或文件属性信息的代码的性能,因为os.direntry对象在扫描目录时如果操作系统提供此信息,则会公开此信息。所有os.direntry方法都可以执行系统调用,但is_dir()和is_file()通常只需要对符号链接进行系统调用;os.direntry.stat()始终需要对Unix进行系统调用,但在Windows上只需要对符号链接进行系统调用。
Python文档
1 2 3 4 5 6 7 8 9 10 11 | import os, sys #open files in directory path ="My Documents" dirs = os.listdir( path ) # print the files in given directory for file in dirs: print (file) |