如何从Python中的目录中的所有子目录中查找最近修改过的文件?

时间:2017-03-30 11:14:24

标签: python file find directory subdirectory

我有一个目录,其中我有很多文件夹,和文件一样好。我想编写一个脚本来查找目录中存在的最新文件的路径和名称,无论是在其子目录中还是在目录本身中。每当我想运行程序时,这将从VSCode运行。早些时候我有这样的事情。它仅适用于目录中的文件,而不适用于子目录中的文件。

files = sorted(os.listdir(path), key=os.path.getctime, reverse = True)
for file in files: #Finds most recent file with '.cpp' extension
    if ".cpp" in file:
        last = file
        break
subprocess.call(
    ["g++", "-std=c++14", path + last]
    )
subprocess.call(
    ["open", path + "./a.out"]
)

这是" ls -ltr"的输出。在终端。最后三行是文件夹。

-rw-r--r--@  1 tanavya.dimri  staff     2182 Mar 23 16:10 UVa_LEDTest.cpp
-rw-r--r--@  1 tanavya.dimri  staff     4217 Mar 23 16:11 OPC_SiruseriMetro.cpp
-rw-r--r--@  1 tanavya.dimri  staff     2645 Mar 23 16:12 UVa_Password.cpp
-rw-r--r--@  1 tanavya.dimri  staff      940 Mar 23 16:13 UVa_8Queens.cpp
-rw-r--r--@  1 tanavya.dimri  staff     1587 Mar 23 20:57 UVa12405_Scarecrow.cpp
-rw-r--r--@  1 tanavya.dimri  staff     3014 Mar 25 19:58 UVa_Zones.cpp
-rw-r--r--@  1 tanavya.dimri  staff     2733 Mar 25 20:07 YogesMM.cpp
-rw-r--r--@  1 tanavya.dimri  staff     1066 Mar 26 22:33 ChefAndTraingles.cpp
-rw-r--r--@  1 tanavya.dimri  staff      993 Mar 27 07:10 untitled.cpp
-rw-r--r--   1 tanavya.dimri  staff       33 Mar 27 21:42 out.out
-rwxr-xr-x   1 tanavya.dimri  staff    15564 Mar 27 22:54 a.out
drwxr-xr-x   8 tanavya.dimri  staff      272 Mar 27 23:35 SpecificAlgorithms
drwxr-xr-x  25 tanavya.dimri  staff      850 Mar 30 12:49 DynamicProgramming
drwxr-xr-x   5 tanavya.dimri  staff      170 Mar 30 16:27 GraphTheory

也许在将来,我的子目录中可能有子目录,所以如果任何建议的脚本也可以在那个场景中工作,那就更感激了。

修改

彼得和让我喜欢这两个答案,谢谢! 我的文件现在:

import os
import subprocess

path = "/Users/tanavya.dimri/Desktop/CompetitiveProgramming/"

most_recent_file = max((os.path.join(root,f) for root,_,the_files in os.walk(path) for f in the_files if f.lower().endswith(".cpp")),key=os.path.getctime)
subprocess.call(
                ["g++", "-std=c++14", most_recent_file]
                )
run_file = max((os.path.join(root,f) for root,_,the_files in os.walk(path) for f in the_files if f.lower() == "a.out"),key=os.path.getctime)
subprocess.call(
                ["open", run_file]
                )

虽然我也喜欢彼得代码的可读性,但它简短易懂。

2 个答案:

答案 0 :(得分:2)

使用os.walk,(忽略目录),而不是os.listdir在嵌套列表推导中提供给sort

files = sorted([os.path.join(root,f) for root,_,the_files in os.walk(path) for f in the_files if f.lower().endswith(".cpp")], key=os.path.getctime, reverse = True)

正如有人提到的,如果您只需要1个文件,则只需将maxkey一起使用(在这种情况下,切换到生成器理解,因为您不需要完整列表提供给sort并优化速度:

most_recent_file = max((os.path.join(root,f) for root,_,the_files in os.walk(path) for f in the_files if f.lower().endswith(".cpp")),key=os.path.getctime)

请注意,您的表达式files = sorted(os.listdir(path), key=os.path.getctime, reverse = True)需要您更改当前目录,除非path不是当前路径,因为listdir返回文件名而不是文件路径(是的,您也是必须过滤掉目录,这会进一步复杂化表达式。上面的解决方案不再有这个问题,因为在排序之前应用了os.path.join

答案 1 :(得分:2)

您可以使用os.walk编写一个通常有用的函数来生成目录中和目录下的所有文件路径:

def filepaths(directory):
    for root, dirs, filenames in os.walk(directory):
        for filename in filenames:
            yield os.path.join(root, filename)

然后你可以编写一个生成器来过滤掉.cpp个文件,确保通过首先将路径转换为小写来比较忽略大小写的情况:

cpps = (filepath for filepath in filepaths(directory)
        if filepath.lower().endswith('.cpp'))

您可以对密钥为os.path.getctime

的文件使用max
latest = max(cpps, key=os.path.getctime)

使用max的一个优点是os.path.getctime只能为每个文件路径调用一次。使用sorted的解决方案效率很低,因为您并不需要按顺序修改所有修改时间,只需要最新版本。将为每次比较调用getctime以使文件按顺序排列。

相关问题