Find Out If File Has Been Modified Within the Last 2 Minutes

Find the files that have been changed in last 24 hours

To find all files modified in the last 24 hours (last full day) in a particular specific directory and its sub-directories:

find /directory_path -mtime -1 -ls

Should be to your liking

The - before 1 is important - it means anything changed one day or less ago.
A + before 1 would instead mean anything changed at least one day ago, while having nothing before the 1 would have meant it was changed exacted one day ago, no more, no less.

how to get files changed in last 5 minutes

You need to unpack, join the file to the root directory and compare:

import os, time

_dir = os.getcwd()
files = (fle for rt, _, f in os.walk(_dir) for fle in f if time.time() - os.stat(
os.path.join(rt, fle)).st_mtime < 300)

print(list(files))

os.stat(filename).st_mtime returns a time which cannot be iterated over, you need to compare that time to the current time, time.time() itself returns the seconds since the epoch so you need to compare the difference between time.time() - os.stat(os.path.join(rt, fle)).st_mtime to the amount of minutes in seconds, i.e 300 in your case.

If you are monitoring directories you might find watchdog useful, the example in the docs does exactly what you want:

import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler

if __name__ == "__main__":
logging.basicConfig(level=logging.INFO,
format='%(asctime)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
path = sys.argv[1] if len(sys.argv) > 1 else '.'
event_handler = LoggingEventHandler()
observer = Observer()
observer.schedule(event_handler, path, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()

It checks the current directory recursively for changes to files and logs any changes to the console.

find the latest file that was modified within last minute in ansible?

This is definitely something possible, you are even close from the solution.

As you might have seen it doing a debug of your find already, the return of it contains a list of files, this list would just be empty if you have no file.

So it become pretty easy to see when the list is empty with Jinja

- debug:
msg: '{{ files.files if files.files|count > 0 else "cannot find any file" }}'

This syntax is using an inline if as well as a count filter.

Regarding the fact that you want the most recent file now, you can also use a set of Jinja filers: the filter sort will help you sort the files by modification time, and the filter first will help you get only the first element of you list.

- debug:
msg: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path }}'

Now you just need to combine both in one long Jinja expression:

- debug:
msg: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path if files.files|count > 0 else "cannot find any file" }}'

In order to copy the file, you will need one extra Jinja filter that is specific to Ansible and that is basename, in order to get the name of the file out of its full path

- debug:
msg: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path | basename if files.files|count > 0 else "cannot find any file" }}'

But you will also need the when statement so your copy will be skipped if there is no matching file:

- name: Copy file, if found                 
copy:
src: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path }}'
dest: '/tmp/{{ (files.files | sort(attribute="mtime", reverse=true) | first).path | basename }}'
when: files.files|count > 0

A full working playbook for you to test:

---
- hosts: localhost
connection: locale

vars:
var_files:
- { 'name': 'a', 'time': 86400 }
- { 'name': 'b', 'time': 30 }
- { 'name': 'c', 'time': 20 }

tasks:
- name: creating a bunch of matching files
file:
path: '/data/{{ item.name }}'
state: touch
with_items: '{{ var_files }}'

- name: aging those files
file:
path: '/data/{{ item.name }}'
modification_time: '{{ "%Y%m%d%H%M.%S" | strftime( ( ansible_date_time.epoch | int ) - item.time ) }}'
with_items: '{{ var_files }}'

- name: find the latest file
find: paths=/data
file_type=file
age=-1m
age_stamp=mtime
register: files

- debug:
msg: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path if files.files|count > 0 else "cannot find any file" }}'

- name: Copy file, if found
copy:
src: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path }}'
dest: '/tmp/{{ (files.files | sort(attribute="mtime", reverse=true) | first).path | basename }}'
when: files.files|count > 0

- name: removing files to test the behaviour with no matching files
file:
path: '/data/{{ item.name }}'
state: absent
with_items: '{{ var_files }}'

- name: find the latest file
find: paths=/data
file_type=file
age=-1m
age_stamp=mtime
register: files

- debug:
msg: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path if files.files|count > 0 else "cannot find any file" }}'

- name: Copy file, if found
copy:
src: '{{ (files.files | sort(attribute="mtime", reverse=true) | first).path }}'
dest: '/tmp/{{ (files.files | sort(attribute="mtime", reverse=true) | first).path | basename }}'
when: files.files|count > 0

And the corresponding output of that playbook

PLAY [localhost] ********************************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************************
ok: [localhost]

TASK [creating a bunch of matching files] *******************************************************************************************************
changed: [localhost] => (item={'name': 'a', 'time': 86400})
changed: [localhost] => (item={'name': 'b', 'time': 30})
changed: [localhost] => (item={'name': 'c', 'time': 20})

TASK [aging those files] ************************************************************************************************************************
changed: [localhost] => (item={'name': 'a', 'time': 86400})
changed: [localhost] => (item={'name': 'b', 'time': 30})
changed: [localhost] => (item={'name': 'c', 'time': 20})

TASK [find the latest file] *********************************************************************************************************************
ok: [localhost]

TASK [debug] ************************************************************************************************************************************
ok: [localhost] => {
"msg": "/data/c"
}

TASK [Copy file, if found] **********************************************************************************************************************
changed: [localhost]

TASK [removing files to test the behaviour with no matching files] ******************************************************************************
changed: [localhost] => (item={'name': 'a', 'time': 86400})
changed: [localhost] => (item={'name': 'b', 'time': 30})
changed: [localhost] => (item={'name': 'c', 'time': 20})

TASK [find the latest file] *********************************************************************************************************************
ok: [localhost]

TASK [debug] ************************************************************************************************************************************
ok: [localhost] => {
"msg": "cannot find any file"
}

TASK [Copy file, if found] **********************************************************************************************************************
skipping: [localhost]

PLAY RECAP **************************************************************************************************************************************
localhost : ok=9 changed=4 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0

find files modified within given time range

-newermt primary doesn't accept a time range in any format. To select files modified within let's say the period A-B, you need two -newermts; one to include files newer than A, the other to exclude files newer than B.

Further, there are two edge cases that need to be dealt with:

  1. The user might enter 08 or 09 as both are valid hours. But as both have a leading zero, Bash would treat them as octal numbers in an arithmetic context, and raise an error since 8 and 9 are not valid digits in base 8.
  2. When the user entered 0, to include files modified at 00:00 too, inclusive -newermt's argument has to be yesterday's 23:59:59.

So, I would do it like this instead:

#!/bin/bash -
LC_COLLATE=C
read -rp 'hour ([0]0-23): ' hour
case $hour in
(0|00)
find /home/mikepnrs \
-newermt 'yesterday 23:59:59' \
! -newermt '00:59:59' ;;
(0[1-9]|1[0-9]|2[0-3])
find /home/mikepnrs \
-newermt "$((10#$hour-1)):59:59" \
! -newermt "$hour:59:59" ;;
(*)
printf 'invalid hour: %q\n' "$hour" >&2
exit 1
esac

Need to find files modified between 15 and 5 minutes ago

Try this :

find . -name '*pattern.txt' -maxdepth 1 -type f \( -mmin -15 -a -mmin +5 \)

Notes

  • the parenthesis are not mandatory here with and : -a, but it's necessary for case with or: -o
  • always use single quotes around the pattern to prevent shell expansion of the wildcard
  • to give a pattern, use -name or -iname
  • for the date/hour, -mmin is the way to go for minutes and -mtime for days.

How to find file accessed/created just few minutes ago

Simply specify whether you want the time to be greater, smaller, or equal to the time you want, using, respectively:

find . -cmin +<time>
find . -cmin -<time>
find . -cmin <time>

In your case, for example, the files with last edition in a maximum of 5 minutes, are given by:

find . -cmin -5


Related Topics



Leave a reply



Submit