如何从 Python 目录的所有子目录中找到最近修改的文件?
How to find most recently modified file from all subdirectories in a directory in Python?
我有一个目录,其中有很多文件夹和文件。我想编写一个脚本来查找目录中存在的最新文件的路径和名称,无论是在其子目录之一中,还是在目录本身中。每当我想 运行 一个程序时,这将是 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
也许在未来,我的子目录中可能会有子目录,所以如果任何建议的脚本也可以在这种情况下工作,我们将不胜感激。
编辑
我喜欢 Peter 和 Jean 的两个答案,非常感谢!
我现在的档案:
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]
)
虽然我也喜欢 Peter 代码的可读性,但它又短又简单。
在提供给 sort
的嵌套列表理解中使用 os.walk
,(忽略目录),而不是 os.listdir
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 个文件,则只需将 max
与 key
一起应用(在这种情况下,切换到生成器理解,因为您不需要完整列表以提供给 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
returns 是文件名而不是文件路径(是的,您还必须过滤掉目录,这会使表达式进一步复杂化。由于在排序之前应用了 os.path.join
,因此使用上述解决方案不再有此问题)
您可以使用 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
将在每次比较时调用以使文件有序。
我有一个目录,其中有很多文件夹和文件。我想编写一个脚本来查找目录中存在的最新文件的路径和名称,无论是在其子目录之一中,还是在目录本身中。每当我想 运行 一个程序时,这将是 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
也许在未来,我的子目录中可能会有子目录,所以如果任何建议的脚本也可以在这种情况下工作,我们将不胜感激。
编辑
我喜欢 Peter 和 Jean 的两个答案,非常感谢! 我现在的档案:
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]
)
虽然我也喜欢 Peter 代码的可读性,但它又短又简单。
在提供给 sort
os.walk
,(忽略目录),而不是 os.listdir
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 个文件,则只需将 max
与 key
一起应用(在这种情况下,切换到生成器理解,因为您不需要完整列表以提供给 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
returns 是文件名而不是文件路径(是的,您还必须过滤掉目录,这会使表达式进一步复杂化。由于在排序之前应用了 os.path.join
,因此使用上述解决方案不再有此问题)
您可以使用 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
将在每次比较时调用以使文件有序。