Sometimes you need to perform an operation on the oldest of a set of files. Using get_oldest_file you could implement an age-based priority queue that processes files from oldest to newest. The list of files you pass in may be from a glob of a single directory or some more elaborate search routine.
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 | import os, glob, time, operator
def get_oldest_file(files, _invert=False):
""" Find and return the oldest file of input file names.
Only one wins tie. Values based on time distance from present.
Use of `_invert` inverts logic to make this a youngest routine,
to be used more clearly via `get_youngest_file`.
"""
gt = operator.lt if _invert else operator.gt
# Check for empty list.
if not files:
return None
# Raw epoch distance.
now = time.time()
# Select first as arbitrary sentinel file, storing name and age.
oldest = files[0], now - os.path.getctime(files[0])
# Iterate over all remaining files.
for f in files[1:]:
age = now - os.path.getctime(f)
if gt(age, oldest[1]):
# Set new oldest.
oldest = f, age
# Return just the name of oldest file.
return oldest[0]
def get_youngest_file(files):
return get_oldest_file(files, _invert=True)
# Example.
files = glob.glob('*.py')
print 'oldest:', get_oldest_file(files)
print 'youngest:', get_youngest_file(files)
|
Of course this is simpler in a shell with something like: ls -t *.py |head -1 but often shelling out is not an option. And this recipe demonstrates some useful time math.
Download
Copy to clipboard
It would be much simplier and faster to hand the task down to built-in sorted function:
Wow, that's quite an improvement. Thanks Mike!
You can actually avoid sorting the whole list.
You need a python version >= 2.5 for min/max with key argument.
source: http://docs.python.org/library/functions.html#min
There is a problem with this solution. If you specify a directory in the os.listdir function the os.path.getctime is not able to find the filenames that the listdir provides.
Hey,
@Micah how can I set a default path in your script, For example I want to search for the youngest file in map X and write it in map Y
I have set already the write map (map Y), but I don't now how to set the default map.
Thanks for a possible solution!
@Sohaib
Correct, this would fix it though. Hope it helps someone
min(os.listdir(log_folder), key=lambda f: os.path.getctime("{}/{}".format(log_folder, f)))