182

With the ls command, is it possible to show only the files created after a specific date, hour...?

I'm asking it because I have a directory with thousand of files.

I want so see all files that were created since yesterday.

I use ls -ltr but I have to wait to see all files...

There is an equivalent of DIRECTORY/SINCE=date from OpenVMS ?

Luc M
  • 4,095
  • 5
  • 30
  • 29

5 Answers5

234

You can use the find command to find all files that have been modified after a certain number of days.

For example, to find all files in the current directory that have been modified since yesterday (24 hours ago) use:

find . -maxdepth 1 -mtime -1

Note that to find files modified before 24 hours ago, you have to use -mtime +1 instead of -mtime -1.

dogbane
  • 29,677
  • 3
    The very thing I would have said. There's no reason to limit yourself to ls here, Luc. – Warren Young Mar 24 '11 at 16:04
  • 39
    With GNU find, there are other possibilities. -mmin 5 lists files modified in the last 5 minutes. -newermt "2011-02-27 13:42" lists files modified since the specified date. You can use -exec ls --color -ld {} + instead of -ls to get the usual color display (if you like colored ls output). – Gilles 'SO- stop being evil' Mar 24 '11 at 20:44
  • 6
    Note the minus sign: find . -mmin -5 – user7543 May 17 '11 at 08:32
  • and -maxdepth 1 can be increased to any n value to search files under subdirectory level too – anshuman Sep 12 '12 at 05:42
  • This is great, except it lists the current directory . also. I had to run this through tail to strip that. Is there a way within find to chop one? – Geoff Dec 27 '12 at 12:44
  • 1
    Found my answer: Use -mindepth 1 to ensure that the current directory . does not get listed. – Geoff Dec 27 '12 at 15:43
  • 5
    for me it works like this: find . -type f -newermt '1/15/2012 18:09:00' – scrat.squirrel Jan 05 '13 at 23:16
  • -newermt was not available on the last server I was working on. -newer does accept files/directories and will only list files newer than that file/directory, though. – Rob Nov 20 '13 at 16:03
  • That's a lot of work to calculate how long ago an arbitrary date was – jbo5112 Jul 13 '19 at 15:25
  • Note that decimal point, e.g. -mtime -1.8 is work. – 林果皞 Jan 04 '21 at 11:40
92
find . -type f -newermt '1/30/2017 0:00:00'

This will find all files modified after a specific date.

nullability
  • 1,028
  • 23
    This has worked for me, except I decided to go for a less ambiguous date format, e.g. find . -type f -newermt '2020-04-01 00:00:00' – ᴍᴇʜᴏᴠ Mar 04 '21 at 07:23
3
ls -ltr | grep "`date | awk '{print $2" "$3}'`"
Anthon
  • 79,293
  • 7
    Hi Trant! While your solution is creative in attempting to respect the question's request to use ls, parsing the output of ls is seldom safe (e.g., what happens with file names including newlines here?), and we like it for answers to not be just one-liners, but rather to explain how they work in as much detail as is relevant. – dhag Apr 10 '15 at 15:58
  • 4
    Issues: (1) On my system, date says Jun 03, but ls says Jun  3, so this doesn’t work.  (2) A week ago, the date was May 27.  ls -l | grep "May 27" would find files modified that day, but also files modified May 27 of any other year — and files with “May 27” in their name.  (And if you think that’s a totally bogus concern, look up “Dec 10”.)  (3) And, if you managed to get date to say Jun 2, grepping for that would find Jun 20 through Jun 29, but not Jun  2 (with two spaces).  … (Cont’d) – G-Man Says 'Reinstate Monica' Jun 04 '15 at 01:33
  • 2
    (Cont’d) …  (4) The OP was using ls -ltr to get the most recently modified files at the end of the listing.  If you’re grepping for a date, there’s no need to do that (except to get the May 27, 2015 files at the end of the listing, after the May 27, 2014, May 27, 2013, etc., files).  (5) In awk, print $2, $3 is equivalent to print $2" "$3, and is much easier to read — especially when there are three other levels of quotes. – G-Man Says 'Reinstate Monica' Jun 04 '15 at 01:37
  • ls -ltr | grep "$(date | awk '{print $2,$3}')" – SergioAraujo May 22 '18 at 12:21
  • Best answer in my opinion. Works and you only need to use everyday commands. – daniel_hck Jan 21 '21 at 00:39
2

Hope this works:

ls -ltr | awk '$6 == "May" && $7 >=01 && $7 <= 31 {print $9}'

Here:

$6 indicates position of month
$7 indicates day of the month

this above command prints all the file names which are created on or after May 1st to May 31st

if you want to print date as well on the console try this

ls -ltr | awk '$6 == "May" && $7 >=01 && $7 <= 31 {print $6"-"$7,$9}'

If you want to specify path of the directory you may try this out

ls -ltr <path>| awk '$6 == "May" && $7 >=01 && $7 <= 31 {print $6"-"$7,$9}'
0

I think these ls commands are far better than using find if the additional file metrics that find (which just returns filenames) does not provide are needed. That said, all the ls solutions seem really cumbersome piping to awk. Why not just use gnu date's built in formatting instead?

ls -ltr directory/ | grep "$(date +"%b %e")" Does the same thing and requires no awk print statements or conditionals. GNU date formatting is really helpful for outputting your date exactly how you need. In this case %b matches the 3 letter month and %e is a space-padded day value matching the format of ls instead of a 0-padded day value that the default date uses.

ls -ltr directory/ | grep "$(date +"%b %e")" Example output:

-rw-r----- 1 ocams ocams       987 Sep  2 01:45 ember_status_2021-245-01_30.log.gz.closed
-rw-r----- 1 ocams ocams      1202 Sep  2 01:45 realmvm_status_2021-245-00_04.log.gz.closed
-rw-r----- 1 ocams ocams      1085 Sep  2 01:45 realmvm_status_2021-245-01_04.log.gz.closed
-rw-r----- 1 ocams ocams    312590 Sep  2 01:45 3-21-244-234712.csv.gz.closed
-rw-r----- 1 ocams ocams    925880 Sep  2 01:45 1-21-245-010728.csv.gz.closed
-rw-r----- 1 ocams ocams    310556 Sep  2 01:45 3-21-245-010238.csv.gz.closed
-rw-r----- 1 ocams ocams      1041 Sep  2 01:45 ember_status_2021-245-00_45.log.gz.closed

If you wanted to more closely match find to get exactly 24 hours you can handle the two different dates (the current day, and the previous day) with an or condition in grep: ls -ltr directory/ | grep "$(date +"%b %e")\|$(date -d -1day +"%b %e")". This is returning 25-48 hours worth of data instead of <24.

ls -ltr directory/ | grep "$(date +"%b %e")\|$(date -d -1day +"%b %e")" Example output:

-rw-r----- 1 ocams ocams    314951 Sep  1 23:45 3-21-244-231707.csv.gz.closed
-rw-r----- 1 ocams ocams    899348 Sep  1 23:45 1-21-244-230205.csv.gz.closed
-rw-r----- 1 ocams ocams    915400 Sep  1 23:45 1-21-244-231708.csv.gz.closed
-rw-r----- 1 ocams ocams    671063 Sep  1 23:45 2-21-244-231708.csv.gz.closed
-rw-r----- 1 ocams ocams    666953 Sep  1 23:45 2-21-244-230205.csv.gz.closed
-rw-r----- 1 ocams ocams       987 Sep  2 01:45 ember_status_2021-245-01_30.log.gz.closed
-rw-r----- 1 ocams ocams      1202 Sep  2 01:45 realmvm_status_2021-245-00_04.log.gz.closed
-rw-r----- 1 ocams ocams      1085 Sep  2 01:45 realmvm_status_2021-245-01_04.log.gz.closed
William
  • 43
  • 1
    Welcome to the site, and thank you for your contribution. A few comments, though: (1) parsing the output of ls is discouraged for a variety of reasons, locale-dependence being one important part. (2) Although find by default only prints the filename, the printf action of find allows output of almost any file attribute, you just need to specify it explicitly. (3) Your approach is very interesting but only works for "absolute" timespans, i.e. you can't say "the last 24h", but only "the last calender day" and the like. – AdminBee Sep 03 '21 at 10:31