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