Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find most recently modified file from all subdirectories in a directory in Python?

I have a directory in which I have many folders, AS WELL as files. I want to write a script that finds the path and name of the most recent file that exists in the directory, either in one of its sub-directories, or in the directory itself. This will be run from VSCode whenever I want to run a program. Earlier I had something like this. It worked ONLY for files in the directory, and not files in sub-directories.

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

Here's the output of "ls -ltr" in Terminal. The last three lines are for folders.

-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

Maybe in the future, I might have sub-directories INSIDE my sub-directories, so if any suggested script can work in that scenario as well, it would be even more appreciated.

EDIT

I liked both the answers, by Peter and Jean, so thanks! My file now:

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

It's short and simple, though I also liked the readability of Peter's code.

like image 861
SinByCos Avatar asked Oct 24 '25 20:10

SinByCos


1 Answers

Use os.walk, (ignoring directories), instead of os.listdir in a nested list comprehension fed to 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)

As someone noted, if you only need 1 file, you can just apply max with a key (and in that case, switch to generator comprehension, since you don't need the full list to feed to sort and optimize speed):

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)

note that your expression files = sorted(os.listdir(path), key=os.path.getctime, reverse = True) needs you to change current directory unless path is not the current path, because listdir returns the file names not the file paths (and yes, you also have to filter out directories, which complexifies the expression further. You don't have this problem anymore with the solution above since os.path.join is applied before sorting)

like image 176
Jean-François Fabre Avatar answered Oct 26 '25 10:10

Jean-François Fabre



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!