0

I'm trying to think of a command or a script that can locate the NEWEST file in a directory and print it's path ONLY IF the file is older than 'X' hours.

The idea behind this is the script to return value (the path of the newest file) only if it's older than 'X' hours. If it returns nothing, it should mean that the newest file is younger than the specified time.

joniop
  • 51
  • 5

3 Answers3

5

In the zsh shell, the following filename globbing pattern would match any non-hidden name:

*

The following would match any regular file with a non-hidden name.

*(.)

To make it act as nullglob in bash, add the qualifier N. Also add D (as in "dot-file") if you want to match hidden names:

*(.ND)

Add mh+3 to match only names of regular files that were modified 4 hours ago or more:

*(.NDmh+3)

Order the matching names by the mtime timestamp:

*(.NDmh+3om)

Pick out the first name (the most recently modified):

*(.NDmh+3om[1])

From bash:

zsh -c 'print -rC1 some/dir/path/*(.NDmh+3om[1])'
Kusalananda
  • 333,661
2

This uses stat from GNU coreutils

# use stat to find the mtime of the newest file
read -r age name < <(stat -c $'%Y\t%n' * | sort -nr | head -1)

number of hours, get the limit epoch time

hrs=4 limit=$((EPOCHSECONDS - hrs * 3600))

print the filename if it's older

((age < limit)) && echo "$name"

Assumptions

  • your $PWD is the directory in question
  • your filenames do not contain newlines
  • your bash version is ... recent (not sure when the EPOCHSECONDS variable was introduced)
glenn jackman
  • 85,964
  • 1
    $EPOCHSECONDS is from zsh (renamed from $SECS in 2003). Added to bash in 5.0 from 2019. With older versions of bash, you can use printf %T (which it borrowed from ksh93), or you can also use date +%s. – Stéphane Chazelas Sep 09 '22 at 22:30
  • Thanks man, added it to a script and works flawlessly. – joniop Sep 12 '22 at 06:24
0

While another solution using stat is cleaner, I decided to post a one-liner because I thought it was interesting and also works.

find -maxdepth 1  -mmin -60  -type f  | grep -q . || ls -tr | tail -1

To explain how this works, first I list all files within the "newer then desired" range. If it finds anything, the grep -q . will output nothing and end execution. However, if it outputs nothing, the grep will return an errorcode, so the or ("||") will cause the ls -tr | tail -1 to run, which will display the oldest entry in the directory.

toppk
  • 657