关于文件:python中的目录树列表

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
          print"* recursive listing, with dirs, but no hidden files:"
          for f in find(root, dirs=True):
              print f
          print

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

      此代码列出给定目录名中所有文件和目录的完整路径。


      虽然os.listdir()可以生成一个文件名和目录名列表,但在python3中,pathlib使其他的工作变得简单。让我们看看你是否和我一样喜欢它。

      要列出目录内容,请构造一个路径对象并获取迭代器:

      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)