Lets say I want to find the youngest/newest *.txt file inside a folder, for example /tmp/? I wrote this little python script for this, but are there better ways to do it?

By youngest I mean the file with the least recent change or creation date? All files have these timestamps. But could I also watch the filesystems folder for file creation events?

import os
import glob

def find_newest_file_type(glob_path):
    # youngest file has biggest timestamp
    youngest = -10
    ultpath = "file_does_not_exist0xfadfadsfadfads.asdfajsdklfj"
    for file in  glob.iglob(glob_path):
        mtime = os.path.getmtime(file)
        if mtime > youngest:
            youngest = mtime
            ultpath = file
    return ultpath

newest = find_newest_file_type("/tmp/*.txt")
  • dandelion (she/her)@lemmy.blahaj.zone
    link
    fedilink
    English
    arrow-up
    5
    ·
    27 days ago

    Are you limited to doing this in python?

    I would normally just use bash:

    find . -type f -name "*.txt" -printf '%T@ %p\n'
    

    this will give you all the files in the current directory that end in .txt, and it will print Unix time and then the filename.

    From man find:

    ...
                  %Ak    File's last access time in the format specified by k, which is either `@' or a directive for the C strftime(3) function.  The following shows an incomplete list  of
                         possible  values for k.  Please refer to the documentation of strftime(3) for the full list.  Some of the conversion specification characters might not be available
                         on all systems, due to differences in the implementation of the strftime(3) library function.
    
                         @      seconds since Jan. 1, 1970, 00:00 GMT, with fractional part.
    
    ...
                  %Tk    File's last modification time in the format specified by k, which is the same as for %A.
    ...
                  %p     File's name.
    ...
    

    OK, so we have a bunch of lines but they’re not in order based on age, so you want to sort them:

    find . -type f -name "*.txt" -printf '%T@ %p\n' | sort -n
    

    from man sort:

           -n, --numeric-sort
                  compare according to string numerical value
    

    So we’re sorting by the number, the largest number will be at the bottom and the smallest at the top. Unix time is the seconds since Jan. 1st 1970, so the largest Unix time is the one closest to now (i.e. it’s the youngest / newest) and will now be listed last in our output.

    To get the youngest single file, all we have to do is just get the last file in that output:

    find . -type f -name "*.txt" -printf '%T@ %p\n' | sort -n | tail -n 1
    

    tail throws away all the output above the last line (-n 1 just means preserve the last line, -n 2 would preserve the last two lines and so forth).

    You probably just want the filename, so you can parse that however you want, I would probably use awk:

    find . -type f -name "*.txt" -printf '%T@ %p\n' | sort -n | tail -n 1 | awk '{print $2}'
    

    Here awk is basically saying “print the second column”, and it parses each column by the space as a separator.

    You could also use cut -f2- -d" " instead to parse:

    find . -type f -name "*.txt" -printf '%T@ %p\n' | sort -n | tail -n 1 | cut -f2- -d" "
    

    Hope this helps!

    • scratsearcher 🔍🔮📊🎲@sopuli.xyzOP
      link
      fedilink
      English
      arrow-up
      1
      ·
      edit-2
      27 days ago

      Are you limited to doing this in python?

      I am really unexperienced in bash, so until now I did even these things in python … but maybe this should change


      When I run this in my /tmp folder like this: find . -type f -name "*.tmp" -printf '%T@ %p\n' | sort -n | tail -n 1 | cut -f2- -d" " It says these things …

      find: ‘./systemd-private…<imagine service name here>’: Permission denied
      

      While the other commenters command ls *.tmp -Art | tail -n 1 does not complain as much, is this because it searches all sub-directories as well?

      • dandelion (she/her)@lemmy.blahaj.zone
        link
        fedilink
        English
        arrow-up
        2
        ·
        edit-2
        27 days ago

        yes, find does look at sub-directories - sorry, I didn’t realize you only wanted it to search in the current dir only and not in sub-directories. You would add -maxdepth 1 to the find command to tell it to only look in the current dir, not further.

        EDIT: and yeah, I would recommend doing tasks like this in bash - you can just type them directly into the terminal. The convenience of writing one-liners like this from memory is hard to beat.

        Once you have enough experience you can just do it from memory, it’s all accessible. Writing a python program and running it every time you want to do a small task like finding the newest file is overkill IMO. But it can be nice to have a little cheatsheet file of bash oneliners you have written in the past to refer to later, esp. as a beginner.

        That said, it’s not wrong to take what I would see as the less convenient route by writing a python script - it can be fun to learn both, and it’s more useful to use python if you need to automate a more complicated task or need that newest file as a part of a larger program you’re writing in python.

        • scratsearcher 🔍🔮📊🎲@sopuli.xyzOP
          link
          fedilink
          English
          arrow-up
          1
          ·
          27 days ago

          Thanks, with maxdepth 1 it works without errors!


          Since the step of finding the youngest file in the folder is part of a larger more complicated workflow/pipeline for me (transcribe the youngest wav file in the tmp folder, name the resulting transcript after the youngest file in the …/recordings_folder/ and copy it there) I will need to integrate it into a python script I think.

          • dandelion (she/her)@lemmy.blahaj.zone
            link
            fedilink
            English
            arrow-up
            2
            ·
            edit-2
            27 days ago

            sure, you could probably also do all those other things in bash too, but you could do it all in python as well 😁

            I tend to use bash more for manipulating files and directories. I would probably write a bash script for all the stuff you’re doing.

            I would probably use python for more complicated logic or when python has some library that lets me do something bash doesn’t easily do.

            Finding and moving files is easy in bash, but automating making changes to an Excel sheet is very difficult to do with bash, so I would use Python to automate changes to an Excel file, for example. There are libraries that exist in python you can import and use for that kind of task.

            Recommended reading: