【问题标题】:How do you get a directory listing sorted by creation date in python?如何在 python 中获得按创建日期排序的目录列表?
【发布时间】:2010-09-15 04:01:34
【问题描述】:

获取目录中所有文件列表的最佳方法是什么,按日期排序 [创建 |修改],使用python,在windows机器上?

【问题讨论】:

    标签: python windows directory


    【解决方案1】:

    我过去曾为 Python 脚本执行此操作,以确定目录中最后更新的文件:

    import glob
    import os
    
    search_dir = "/mydir/"
    # remove anything from the list that is not a file (directories, symlinks)
    # thanks to J.F. Sebastion for pointing out that the requirement was a list 
    # of files (presumably not including directories)  
    files = list(filter(os.path.isfile, glob.glob(search_dir + "*")))
    files.sort(key=lambda x: os.path.getmtime(x))
    

    根据文件 mtime,这应该可以满足您的需求。

    编辑:请注意,如果需要,您还可以使用 os.listdir() 代替 glob.glob() - 我在原始代码中使用 glob 的原因是我想使用glob 仅搜索具有特定文件扩展名集的文件, glob() 更适合。使用 listdir 如下所示:

    import os
    
    search_dir = "/mydir/"
    os.chdir(search_dir)
    files = filter(os.path.isfile, os.listdir(search_dir))
    files = [os.path.join(search_dir, f) for f in files] # add path to each file
    files.sort(key=lambda x: os.path.getmtime(x))
    

    【讨论】:

    • glob() 很好,但请记住,它会跳过以句点开头的文件。 *nix 系统将此类文件视为隐藏文件(因此从列表中忽略它们),但在 Windows 中它们是普通文件。
    • 这些解决方案不会从列表中排除目录。
    • 您的 os.listdir 解决方案缺少 os.path.join: files.sort(lambda x,y: cmp(os.path.getmtime(os.path.join(search_dir,x)) , os.path.getmtime(os.path.join(search_dir,y)))))
    • files.sort(key=lambda fn: os.path.getmtime(os.path.join(search_dir, fn)))
    • 只有files.sort(key=os.path.getmtime) 应该可以工作(没有lambda)。
    【解决方案2】:

    也许你应该使用 shell 命令。在 Unix/Linux 中, find piped with sort 可能会做你想做的事。

    【讨论】:

      【解决方案3】:

      这是一个单行:

      import os
      import time
      from pprint import pprint
      
      pprint([(x[0], time.ctime(x[1].st_ctime)) for x in sorted([(fn, os.stat(fn)) for fn in os.listdir(".")], key = lambda x: x[1].st_ctime)])
      

      这会调用 os.listdir() 来获取文件名列表,然后调用 os.stat() 来获取每个文件名的创建时间,然后根据创建时间进行排序。

      请注意,此方法只为每个文件调用一次 os.stat(),这将比为排序中的每次比较调用它更有效。

      【讨论】:

      • 这几乎不是 pythonic,虽然它确实解决了这个问题(免责声明:没有测试代码)。
      • 此解决方案不会从列表中排除目录。
      • @Constantin: 没错,但是快速 [... if stat.S_ISREG(x)] 可以解决这个问题。
      【解决方案4】:

      这是我的版本:

      def getfiles(dirpath):
          a = [s for s in os.listdir(dirpath)
               if os.path.isfile(os.path.join(dirpath, s))]
          a.sort(key=lambda s: os.path.getmtime(os.path.join(dirpath, s)))
          return a
      

      首先,我们建立一个文件名列表。 isfile() 用于跳过目录;如果应该包含目录,则可以省略它。然后,我们使用修改日期作为键对列表进行就地排序。

      【讨论】:

      • 它按从旧到新排序。当我想要 5 个最新文件时,我必须执行以下操作 a[-5:]
      【解决方案5】:
      sorted(filter(os.path.isfile, os.listdir('.')), 
          key=lambda p: os.stat(p).st_mtime)
      

      您可以使用os.walk('.').next()[-1] 而不是使用os.path.isfile 进行过滤,但这会在列表中留下无效的符号链接,os.stat 将无法处理它们。

      【讨论】:

        【解决方案6】:

        更新:在 Python 3 中按修改日期对dirpath 的条目进行排序:

        import os
        from pathlib import Path
        
        paths = sorted(Path(dirpath).iterdir(), key=os.path.getmtime)
        

        (将@Pygirl's answer放在这里以提高知名度)

        如果您已经有一个文件名列表files,则在 Windows 上按创建时间对其进行就地排序(确保该列表包含绝对路径):

        files.sort(key=os.path.getctime)
        

        您可以获得的文件列表,例如使用glob,如@Jay's answer 所示。


        旧答案 这是@Greg Hewgill's answer 的更详细版本。是最符合题目要求的。它区分了创建日期和修改日期(至少在 Windows 上)。

        #!/usr/bin/env python
        from stat import S_ISREG, ST_CTIME, ST_MODE
        import os, sys, time
        
        # path to the directory (relative or absolute)
        dirpath = sys.argv[1] if len(sys.argv) == 2 else r'.'
        
        # get all entries in the directory w/ stats
        entries = (os.path.join(dirpath, fn) for fn in os.listdir(dirpath))
        entries = ((os.stat(path), path) for path in entries)
        
        # leave only regular files, insert creation date
        entries = ((stat[ST_CTIME], path)
                   for stat, path in entries if S_ISREG(stat[ST_MODE]))
        #NOTE: on Windows `ST_CTIME` is a creation date 
        #  but on Unix it could be something else
        #NOTE: use `ST_MTIME` to sort by a modification date
                
        for cdate, path in sorted(entries):
            print time.ctime(cdate), os.path.basename(path)
        

        例子:

        $ python stat_creation_date.py
        Thu Feb 11 13:31:07 2009 stat_creation_date.py
        

        【讨论】:

        • 这非常有效。我正在尝试将两个目录 cdate 相互比较。有没有办法比较两个 cdates 之间的秒数?
        • @malcmcmul: cdate 是自纪元以来的浮点秒数。
        • 这可行,但最简洁的解决方案是stackoverflow.com/a/4500607/68534
        • @jmoz:你的意思是像this。您链接的解决方案是错误的:它不过滤常规文件。注意:我的解决方案每个 dir.entry 调用一次 stat
        • 见谅,Sabastian提供的链接更简洁!谢谢。
        【解决方案7】:

        有一个os.path.getmtime 函数给出自纪元以来的秒数 并且应该比os.stat 更快。

        import os 
        
        os.chdir(directory)
        sorted(filter(os.path.isfile, os.listdir('.')), key=os.path.getmtime)
        

        【讨论】:

          【解决方案8】:

          这是学习的基本步骤:

          import os, stat, sys
          import time
          
          dirpath = sys.argv[1] if len(sys.argv) == 2 else r'.'
          
          listdir = os.listdir(dirpath)
          
          for i in listdir:
              os.chdir(dirpath)
              data_001 = os.path.realpath(i)
              listdir_stat1 = os.stat(data_001)
              listdir_stat2 = ((os.stat(data_001), data_001))
              print time.ctime(listdir_stat1.st_ctime), data_001
          

          【讨论】:

            【解决方案9】:

            如果您想按日期顺序读取具有特定扩展名的文件(Python 3),这是我使用不带过滤器的 glob 的答案。

            dataset_path='/mydir/'   
            files = glob.glob(dataset_path+"/morepath/*.extension")   
            files.sort(key=os.path.getmtime)
            

            【讨论】:

              【解决方案10】:

              不改变目录:

              import os    
              
              path = '/path/to/files/'
              name_list = os.listdir(path)
              full_list = [os.path.join(path,i) for i in name_list]
              time_sorted_list = sorted(full_list, key=os.path.getmtime)
              
              print time_sorted_list
              
              # if you want just the filenames sorted, simply remove the dir from each
              sorted_filename_list = [ os.path.basename(i) for i in time_sorted_list]
              print sorted_filename_list
              

              【讨论】:

                【解决方案11】:

                如果文件是指向不存在文件的符号链接,Alex Coventry 的回答将产生异常,以下代码更正了该回答:

                import time
                import datetime
                sorted(filter(os.path.isfile, os.listdir('.')), 
                    key=lambda p: os.path.exists(p) and os.stat(p).st_mtime or time.mktime(datetime.now().timetuple())
                

                当文件不存在时,使用 now(),符号链接将位于列表的最后。

                【讨论】:

                  【解决方案12】:

                  在 python 3.5+ 中

                  from pathlib import Path
                  sorted(Path('.').iterdir(), key=lambda f: f.stat().st_mtime)
                  

                  【讨论】:

                  • 创建日期,请改用f.stat().st_ctime
                  【解决方案13】:

                  这里有几行简单的查找扩展并提供排序选项

                  def get_sorted_files(src_dir, regex_ext='*', sort_reverse=False): 
                      files_to_evaluate = [os.path.join(src_dir, f) for f in os.listdir(src_dir) if re.search(r'.*\.({})$'.format(regex_ext), f)]
                      files_to_evaluate.sort(key=os.path.getmtime, reverse=sort_reverse)
                      return files_to_evaluate
                  

                  【讨论】:

                    【解决方案14】:
                    # *** the shortest and best way ***
                    # getmtime --> sort by modified time
                    # getctime --> sort by created time
                    
                    import glob,os
                    
                    lst_files = glob.glob("*.txt")
                    lst_files.sort(key=os.path.getmtime)
                    print("\n".join(lst_files))
                    

                    【讨论】:

                    • 请提供上下文
                    • “最佳”是主观的。如果您解释为什么您认为这是最好的方法,您的答案会更好。
                    • 如果你想要“最好的”,你当然不要使用 glob,因为它真的很慢。
                    【解决方案15】:

                    对于os.scandir 的完整性(比pathlib 快2 倍):

                    import os
                    sorted(os.scandir('/tmp/test'), key=lambda d: d.stat().st_mtime)
                    

                    【讨论】:

                      【解决方案16】:
                      from pathlib import Path
                      import os
                      
                      sorted(Path('./').iterdir(), key=lambda t: t.stat().st_mtime)
                      

                      sorted(Path('./').iterdir(), key=os.path.getmtime)
                      

                      sorted(os.scandir('./'), key=lambda t: t.stat().st_mtime)
                      

                      其中m时间是修改时间。

                      【讨论】:

                        【解决方案17】:

                        这是我的版本:

                        import os
                        
                        folder_path = r'D:\Movies\extra\new\dramas' # your path
                        os.chdir(folder_path) # make the path active
                        x = sorted(os.listdir(), key=os.path.getctime)  # sorted using creation time
                        
                        folder = 0
                        
                        for folder in range(len(x)):
                            print(x[folder]) # print all the foldername inside the folder_path
                            folder = +1
                        

                        【讨论】:

                        • 在我的代码中,文件按从旧到新排序。要首先获取最新的文件名或文件夹,您需要在文件列表中添加 reverse = True(在我的情况下是 x)。所以,x = sorted(os.listdir(), key=os.path.getctime, reverse=True)
                        【解决方案18】:

                        原来os.listdir 按上次修改排序,但相反,所以你可以这样做:

                        import os
                        last_modified=os.listdir()[::-1]
                        

                        【讨论】:

                        • “结果是 os.listdir 按上次修改排序,但反向排序” - 不,它没有。该文档明确指出:“os.listdir(path='.') 返回一个列表,其中包含路径给定的目录中条目的名称。该列表按任意顺序”(强调我的)
                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2016-03-30
                        相关资源
                        最近更新 更多