79

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...)
codeforester
  • 39,467
  • 16
  • 112
  • 140
sanjuro8998
  • 1,161
  • 2
  • 14
  • 22

8 Answers8

185

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.
codebeard
  • 2,356
  • 2
  • 13
  • 15
  • Anyone knows how to sort the resulting list on the time? – Koshmaar Jun 15 '15 at 15:10
  • 2
    @Koshmaar Depending on the situation, you can use something like `find ... -exec ls -dilst {} +` The t option to ls will make it sort by time; see the ls man page for other sort options. – codebeard Jun 18 '15 at 08:09
  • 3
    @Koshmaar This won't work if there are too many files though as the exec commands will start being split. In that case you'd need to use something like `find ... -printf '%C@ %p\n' | sort` – codebeard Jun 18 '15 at 08:16
  • try to execute find . -newermt $(date -d "-2 days" +"%Y-%m-%d %k:%M:%S") ! -newermt $(date -d "-1 days" +"%Y-%m-%d %k:%M:%S") -ls return error find: paths must precede expression: `14:33:20' why? – Nikolay Baranenko Sep 03 '19 at 11:37
  • I think one should use `-Btime` or `-newerBt` instead, strictly for creation time, while `c` is for file changes – ArcherEX Jun 05 '21 at 20:44
58

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.

galoget
  • 722
  • 9
  • 15
frank42
  • 675
  • 5
  • 6
20

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
Jason Slobotski
  • 1,386
  • 14
  • 18
  • 3
    Like a charm. Thanks Jason. Easy to read, easy to write and just with the desired functionality. Did not know the `-newerXY` trick and I have discovered it thanks you your answer. – Xavi Montero Nov 29 '16 at 18:59
  • I think you meant to write `\! -newermt 20130901` – Devon Jan 17 '22 at 23:18
  • @papo - His answer did not contain this solution when I posted this response. It was likely included in his answer after mine was posted. – Jason Slobotski May 18 '23 at 17:39
  • 1
    I see. My bad, I removed my comment about duplicate answer and will check that next time I'll come across multiple identical answers. – papo May 30 '23 at 10:25
11

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")
EvilKittenLord
  • 908
  • 4
  • 8
  • I used the second option but I got this error: Invalid character in date/time specification. Usage: date [-u] [+Field Descriptors] Invalid character in date/time specification. Usage: date [-u] [+Field Descriptors] find: Specify a decimal integer for -mtime Usage: find [-H | -L] path-list [predicate-list] – sanjuro8998 Aug 20 '13 at 15:58
  • AIX... Here's an IBM reference on the DATE command in AIX. http://pic.dhe.ibm.com/infocenter/aix/v7r1/index.jsp?topic=%2Fcom.ibm.aix.cmds%2Fdoc%2Faixcmds2%2Fdate.htm If you can figure out how to print the date in AIX, you can use it with the second command. Sorry, I'm not an AIX guru. – EvilKittenLord Aug 20 '13 at 16:30
  • this worked for me `find . -maxdepth 1 -mmin -$(echo $(date +%s) - $(date +%s -d"Sep 9, 2015 15:03:00") | bc -l | awk '{print $1 / 60}' ) -mmin +$(echo $(date +%s) - $(date +%s -d"Sep 9, 2015 16:21:00") | bc -l | awk '{print $1 / 60}' ) -exec ls -ld --time-style=full-iso {} \;` – marcobazzani Sep 14 '15 at 11:07
  • 7
    2nd command doesn't work ;( `$ ls -cl test_file -rw------- 1 v v 0 Nov 16 22:00 test_file $ find . -mindepth 1 -maxdepth 1 -mtime $(date +%s -d"Nov 16, 2015 22:00:00") -mtime $(date +%s -d"Nov 16, 2015 22:01:00") $` – atti Nov 16 '15 at 19:01
  • 11
    Second command is not correct. `date +%s` returns *seconds* since 1970, but `find -mtime` expects *days before today*: `-mtime n File's data was last modified n*24 hours ago.` I would recommend @codebeard's [answer](http://stackoverflow.com/a/23508622/2267932) which is more convenient. – MarSoft Feb 10 '16 at 17:06
  • `mtime` does not test for newer/older than a specified date, it tests if the difference between the last modification date and now is exactly a given time interval unless `+` or `-` is specified. `-ctime 2w` will only find files that were last modified two weeks ago, not files that where modified three weeks ago and not files that where modified one week ago. If no unit (`w`) is given, the unit is implicit days. And `-mtime` is wrong to begin with, poster asked about file creation, that would be `-Btime`. – Mecki Oct 29 '19 at 11:30
  • The answer from @codebeard is indeed more convenient. if you don't have a version that supports it, this is a little simpler version of @marcobazzani's comment: `find . -mmin -$(echo "($(date +%s) - $(date +%s -d"2020-04-15 09:00:00"))/60"|bc) -mmin +$(echo "($(date +%s) - $(date +%s -d"2021-04-16 10:35:00"))/60"|bc)` which gets all files that have been modified between 2020-04-15 9:00 and 2020-04-16 10:35 to the minute resolution (mmin instead of using mtime which has day resolution). – Dolf Andringa May 19 '21 at 03:38
7

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
choroba
  • 231,213
  • 25
  • 204
  • 289
  • Will it work if I just copy and paste it on the terminal and execute? I can't create any file with my role to use it as a script – sanjuro8998 Aug 20 '13 at 15:59
  • @user2576376: If your shell is bash, it should. – choroba Aug 20 '13 at 16:13
  • What does it means? I'm sorry, not familiar with linux ... I'm executing these comamnds on windows via telnet (command prompt), does it help? – sanjuro8998 Aug 20 '13 at 16:18
  • 3
    @user2576376: If you are not familiar with the target system, do not run any commands in telnet. Find someone who knows what to do. – choroba Aug 20 '13 at 16:20
4

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"
galoget
  • 722
  • 9
  • 15
hizlan erpak
  • 309
  • 2
  • 3
  • answer identical to 6 years earlier answer by @codebeard except here is no description – papo Jan 07 '21 at 15:08
2

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

galoget
  • 722
  • 9
  • 15
DrBeco
  • 11,237
  • 9
  • 59
  • 76
-1

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
Dominique
  • 16,450
  • 15
  • 56
  • 112
avivamg
  • 12,197
  • 3
  • 67
  • 61