Find files created 30 minutes before AND after a given file - UNIX - linux

I am trying to figure out the command to display all files created 30 minutes (as an example) before and after another file was created. So far I managed to find files newer than that file
but I cannot work out how to look for both before and after given time.
A command I have used:
find -type f -newer file.txt -cmin -30
This works fine but only does half of what I am trying to do.
Also, I need to modify that to search for setuid files only, which I THINK I can do by adding the -perm -4000 in that command.
Any suggestions?

As far as I know there is no way to find file creation time.
You can try by modification time (this will get all files last-modified between 5th and 8th)
find . -type f -newermt 2012-10-05 ! -newermt 2012-10-08
(or access time replace newermt with newerat)
newerXY is flag to compare timestamps of current file with reference (see man find for more info).
According to man find (on my debian) there are 4 flags (aside from t to interpret directly as time)
a The access time of the file reference
B The birth time of the file reference
c The inode status change time of reference
m The modification time of the file reference
You can also try with 'B' birth time but it does not work for me, gives me error. I don't know why it is included in the man page
compare to another file
find / -newer file
find / ! -newer file
You can create temp file (one with modification time 30 min before the target file, another 30 mins after)
touch -d `stat -c %y test.txt` - 30 temp/before_temp
touch -d `stat -c %y test.txt` + 30 temp/after_temp
find / -newer temp/before_temp ! -newer temp/after_temp
touch -d takes a date option, so if you add and subtract correctly, this should work.

Related

Find all .py files across directory and subdirectories, fetch the last modified date of all and return the max date in a specific format

I have been struggling to do this. I have multiple .py files located in my directory and subdirectories. I want to find and list all of them with their date and time and return the date and time of the last updated .py file in a variable in the format "+%m-%d-%Y %H:%M:%S".
How can I achieve this?
As of now, I'm able to reach only at this stage where it shows me the stats of the last modified date in terminal. Below is the command I'm using:
find . -path ./ABC -prune -false -o -name '*.py' -exec ls -lat {} + | head -n1
Here I have specifically mentioned not to search in the ./ABC folder.
The output of the above command is:
-rw-rw----+ 1 owner server 8263 Jul 8 09:09 ./apps/Test.py
I'm looking for a way where I can return the date and time of the last updated file (./apps/Test.py in this case) in a variable with the format like 07-08-2021 09:09:30.
Just find ... -printf. See man find.
find . -printf "%Tm-%Td-%TY %TH:%TM:%TS\t%p\n"
I see find output prints seconds with fractional part. You can filter them with sed.

Find files in created between a date range

I use AIX via telnet here at work, and I'd like to know how to find files in a specific folder between a date range. For example: I want to find all files in folder X that were created between 01-Aug-13 and 31-Aug-13.
Observations:
The touch trick (where you create two empty files to use the -newer option) does not work for me, once the user roles that I have on the server does not allow me to create files.
I need to find between specific dates, not days (like: files that were created more than 30 days ago, etc...)
If you use GNU find, since version 4.3.3 you can do:
find -newerct "1 Aug 2013" ! -newerct "1 Sep 2013" -ls
It will accept any date string accepted by GNU date -d.
You can change the c in -newerct to any of a, B, c, or m for looking at atime/birth/ctime/mtime.
Another example - list files modified between 17:30 and 22:00 on Nov 6 2017:
find -newermt "2017-11-06 17:30:00" ! -newermt "2017-11-06 22:00:00" -ls
Full details from man find:
-newerXY reference
Compares the timestamp of the current file with reference. The reference argument is normally the name of a file (and one of its timestamps is used
for the comparison) but it may also be a string describing an absolute time. X and Y are placeholders for other letters, and these letters select
which time belonging to how reference is used for the comparison.
a The access time of the file reference
B The birth time of the file reference
c The inode status change time of reference
m The modification time of the file reference
t reference is interpreted directly as a time
Some combinations are invalid; for example, it is invalid for X to be t. Some combinations are not implemented on all systems; for example B is not
supported on all systems. If an invalid or unsupported combination of XY is specified, a fatal error results. Time specifications are interpreted as
for the argument to the -d option of GNU date. If you try to use the birth time of a reference file, and the birth time cannot be determined, a fatal
error message results. If you specify a test which refers to the birth time of files being examined, this test will fail for any files where the
birth time is unknown.
Try the following command:
find /var/tmp -mtime +2 -a -mtime -8 -ls
This will allow you to find files in /var/tmp folder that are older than 2 days but not older than 8 days.
Some good solutions on here. Wanted to share mine as well as it is short and simple.
I'm using find (GNU findutils) 4.5.11
$ find search/path/ -newermt 20130801 \! -newermt 20130831
You can use the below to find what you need.
Find files older than a specific date/time:
find ~/ -mtime $(echo $(date +%s) - $(date +%s -d"Dec 31, 2009 23:59:59") | bc -l | awk '{print $1 / 86400}' | bc -l)
Or you can find files between two dates. First date more recent, last date, older. You can go down to the second, and you don't have to use mtime. You can use whatever you need.
find . -mtime $(date +%s -d"Aug 10, 2013 23:59:59") -mtime $(date +%s -d"Aug 1, 2013 23:59:59")
Use stat to get the creation time. You can compare the time in the format YYYY-MM-DD HH:MM:SS lexicographically.
This work on Linux with modification time, creation time is not supported. On AIX, the -c option might not be supported, but you should be able to get the information anyway, using grep if nothing else works.
#! /bin/bash
from='2013-08-01 00:00:00.0000000000' # 01-Aug-13
to='2013-08-31 23:59:59.9999999999' # 31-Aug-13
for file in * ; do
modified=$( stat -c%y "$file" )
if [[ $from < $modified && $modified < $to ]] ; then
echo "$file"
fi
done
You can use the following commands to list files between 2 specific dates:
Search on current (.) directory:
find . -type f -newermt "2019-01-01" ! -newermt "2019-05-01"
Search on /var/any/directory/ directory:
find /var/any/directory/ -type f -newermt "2019-01-01" ! -newermt "2019-05-01"
Script oldfiles
I've tried to answer this question in a more complete way, and I ended up creating a complete script with options to help you understand the find command.
The script oldfiles is in this repository
To "create" a new find command you run it with the option -n (dry-run), and it will print to you the correct find command you need to use.
Of course, if you omit the -n it will just run, no need to retype the find command.
Usage:
oldfiles [-v...] ([-h|-V|-n] | {[(-a|-u) | (-m|-t) | -c] (-i | -d | -o| -y | -g) N (-\> | -\< | -\=) [-p "pat"]})
Where the options are classified in the following groups:
Help & Info:
-h, --help : Show this help.
-V, --version : Show version.
-v, --verbose : Turn verbose mode on (cumulative).
-n, --dry-run : Do not run, just explain how to create a "find" command
Time type (access/use, modification time or changed status):
-a or -u : access (use) time
-m or -t : modification time (default)
-c : inode status change
Time range (where N is a positive integer):
-i N : minutes (default, with N equal 1 min)
-d N : days
-o N : months
-y N : years
-g N : N is a DATE (example: "2017-07-06 22:17:15")
Tests:
-p "pat" : optional pattern to match (example: -p "*.c" to find c files) (default -p "*")
-\> : file is newer than given range, ie, time modified after it.
-< : file is older than given range, ie, time is from before it. (default)
-= : file that is exactly N (min, day, month, year) old.
Example:
Find C source files newer than 10 minutes (access time) (with verbosity 3):
oldfiles -a -i 10 -p"*.c" -\> -nvvv
Starting oldfiles script, by beco, version 20170706.202054...
oldfiles -vvv -a -i 10 -p "*.c" -\> -n
Looking for "*.c" files with (a)ccess time newer than 10 minute(s)
find . -name "*.c" -type f -amin -10 -exec ls -ltu --time-style=long-iso {} +
Dry-run
Find H header files older than a month (modification time) (verbosity 2):
oldfiles -m -o 1 -p"*.h" -\< -nvv
Starting oldfiles script, by beco, version 20170706.202054...
oldfiles -vv -m -o 1 -p "*.h" -\< -n
find . -name "*.h" -type f -mtime +30 -exec ls -lt --time-style=long-iso {} +
Dry-run
Find all (*) files within a single day (Dec, 1, 2016; no verbosity, dry-run):
oldfiles -mng "2016-12-01" -\=
find . -name "*" -type f -newermt "2016-11-30 23:59:59" ! -newermt "2016-12-01 23:59:59" -exec ls -lt --time-style=long-iso {} +
Of course, removing the -n the program will run the find command itself and save you the trouble.
I hope this helps everyone finally learn this {a,c,t}{time,min} options.
The LS output:
You will also notice that the ls option ls OPT changes to match the type of time you choose.
Link to clone/download of the oldfiles script:
https://github.com/drbeco/oldfiles
Explanation: Use unix command find with -ctime (creation time) flag.
The find utility recursively descends the directory tree for each path listed, evaluating an expression (composed of the 'primaries' and 'operands') in terms of each file in the tree.
Solution: According to official documentation:
-ctime n[smhdw]
If no units are specified, this primary evaluates to true if the difference
between the time of last change of file status information and the time find
was started, rounded up to the next full 24-hour period, is n 24-hour peri-
ods.
If units are specified, this primary evaluates to true if the difference
between the time of last change of file status information and the time find
was started is exactly n units. Please refer to the -atime primary descrip-
tion for information on supported time units.
Formula:
find <path> -ctime +[number][timeMeasurement] -ctime -[number][timeMeasurment]
Examples:
1.Find everything that were created after 1 week ago and before 2 weeks ago.
find / -ctime +1w -ctime -2w
2.Find all javascript files (.js) in current directory that were created between 1 day ago to 3 days ago.
find . -name "*\.js" -type f -ctime +1d -ctime -3d

Finding files modified within an hour of another file

If i have 3 files called 1.txt,2.txt and 3.txt for example and they were created an hour apart, say 1pm 2pm and 3pm respectively. What I need is a command that finds all files modified within an hour of a specific file.
I'm in the same directory as the files in the terminal and all files are setuid permission
I've been trying:
find . -type f -perm -4000 -newer 2.txt -mmin -60 -print
This should return 3.txt but it doesn't
What would use to file created in the hour before or after 2.txt?
Try this
touch /tmp/temp -t time1
touch /tmp/ntemp -t time2
find . -newer /tmp/temp -a ! -newer /tmp/ntemp -exec ls -l {} \; 2>/dev/null
where
time1 = time of file creation - 1hr
time2 = time of file creation + 1hr
Ex:
time1 = 201210041500
time2 = 201210041700
Here is my logic -
First get time of last access of file in seconds since Epoch in some variable.
time_in_sec=$(stat -c %X 2.txt)
Get the time of last hour ( ie 3600 seconds back )
one_hr_old_time_in_sec=`expr $time_in_sec - 3600`
Convert it into format suitable for find command
newerthan=$(date -d #$one_hr_old_time_in_sec '+%m-%d-%y%n %H:%M:%S')
Convert time of original file in format suitable for find command
olderthan=$(date -d #$time_in_sec '+%m-%d-%y%n%H:%M:%S')
Get the list of files modified between two time periods using find command
find . -newermt "$newerthan" ! -newermt "$olderthan" -print
If it works you can write a small shell script which will take file name as parameter and can try for +3600 also.
Honestly, I haven't tried it. Hope it works !
The previous solution can be simplified since -newermt shall accept the same formats than 'date' including #N for N seconds since epoch.
Also for the 'stat' command it is probably better to use -Y (the time of last modification) instead of -X (the time of last access).
So the command to find the files modified + or - 1 hours of 2.txt is
N=$(stat -c %Y 2.txt)
find . -newermt #$((N-3600)) ! -newermt #$((N+3600)) -print
If you are running this after 4pm, given your example, it makes sense that it wouldn't return 3.txt, as -newer 2.txt -mmin -60 means "modified in the last 60 minutes, and more recently than 2.txt", not "modified less than 60 minutes after 2.txt". I don't think find currently has options to do what you're wanting (at least, the version I have doesn't), but it shouldn't be too hard to script in python or perl.

Finding files by creation time of another file

What I need to do is find files by the creation time of another file. For example if i create a file at 9am and later i wanted to find all the files created 1 hour after it or 1 hour before it. How would i do that?
I've tried experimenting with "-newer" whilst using "find" but I think "xargs" is what i need to be using.
Thanks
I know this is ooooold, but since I was looking for the same thing...
Here's a oneliner version, basically using the same approach as above:
Modified at least one hour after:
find . -newermt "$(date -d "$(stat -c %y reference_file) + 1 hour")"
Modified one hour before or more:
find . -not -newermt "$(date -d "$(stat -c %y reference_file) - 1 hour")"
Modified within the timespan from one hour before to one hour after
find . -newermt "$(date -d "$(stat -c %y reference_file) - 1 hour")" -not -newermt "$(date -d "$(stat -c %y reference_file) + 1 hour")"
Replace reference_file with the file of your choice. You can of course also use othe timespans than 1 hour
How it works
stat -c %y reference_file will return the modification time.
date -d "[...] + 1 hour" will manupulate the date string to one hour later.
find . -newermt "[...]" will find files with modification time (m) newer than given time (t)
All this requires GNU find 4.3.3 or greater (for -newerXY) and GNU date (to support -d and the complex date strings)
After looking at this I found a way to do this, although it is not the nicest solution as it requires integer arithmetic to be done on time.
The idea is to take the seconds since Unix epoch (aka Unix time) from your reference file, do some integer arithmetic on this to get your offset time (one hour before, or after in your example). Then you use find with the -newer parameter.
Example code:
# Get the mtime of your reference file in unix time format,
# assumes 'reference_file' is the name of the file you're using as a benchmark
reference_unix_time=$(ls -l --time-style=+%s reference_file | awk '{ print $6 }')
# Offset 1 hour after reference time
let unix_time_after="$reference_unix_time+60*60"
# Convert to date time with GNU date, for future use with find command
date_time=$(date --date #$unix_time_after '+%Y/%m/%d %H:%M:%S')
# Find files (in current directory or below)which are newer than the reference
# time + 1hour
find . -type f -newermt "$date_time"
For your example of file created upto one hour before the reference file you could use
# Offset 1 hour before reference time
let unix_time_before="$reference_unix_time-60*60"
# Convert to date time with GNU date...
date_time=$(date --date #$unix_time_before '+%Y/%m/%d %H:%M:%S')
# Find files (in current directory or below which were generated
# upto 1 hour before the reference file
find . -type f -not -newermt "$date_time"
Note that all the above is based on the last modification time of files.
The above has been tested with GNU Find (4.5.10), GNU Date (8.15) and GNU Bash (4.2.37).

Is there any way to find out changed file after some date in whole project code?

see i am working in one BIG project source code Now i want to know which files are modified after some date.
Is there any command or any way to get that..
i have tried
# ls -R -l
but here it shows all file with last modified data but i want to filter this output by some data ...
so is there any way to do this in linux? is there any tool available for this?
#set timestamp for file
touch --date "2011-12-31" /tmp/foo
# Find files newer than 2011/Dec/31, in /some/files
find /some/files -newer /tmp/foo
Use find command with mtime arguments: Some examples are here or here
For example, list files changed in last 7 days...
find / -type f -mtime -7
For fine grained search you may try -mmin argument. See an example discussed in another SE site: Find All files older than x minutes
You should use find with -newerXY option.
m – modification time of the file reference
t – reference is interpreted directly as a time
All files modified after 2022-12-01 (inclusive):
find . -type f -newermt 2022-12-01

Resources