4

Usually the date +%d gives the output 08 for the current date, 08/10/2017. But when I do the ls -lrt on a path, the date format is like Oct 8 15:03, so, how do I get the files of the current date?

I'm using the command

ls -lrt XYZ.LOG* |grep "$(date +'%b %d')" |awk '{print $9}'

but it's not giving me the file of today's date (08/10/2017) although it gives me correct output for the dates 10 - 31st of any month.

6

This is cheating a bit, but it works.

First create an empty reference file with a specific timestamp, namely midnight:

touch -d "$(date +%FT00:00:00)" /tmp/midnight

Then find files that are newer than this file:

find . -type f -newer /tmp/midnight

If you want ls-like output from find rather than just the pathnames:

find . -type f -newer /tmp/midnight -ls

If you want to find files matching the pattern XYZ.LOG*:

find . -type f -name 'XYZ.LOG*' -newer /tmp/midnight -ls

If you have GNU find, you may bypass the temporary file and use

find . -type f -newermt 0

to get files modified since midnight.


Related: Why *not* parse `ls`?

  • At least with recent versions of GNU find, you can skip the temp file and use time strings directly with the -newerXY test e.g. find . -type f -newermt yesterday – steeldriver Oct 8 '17 at 14:19
  • @steeldriver Ah, but yesterday would refer to "this time yesterday" which may cause files modified before midnight to be returned. – Kusalananda Oct 8 '17 at 14:23
  • @steeldriver 0 works though... – Kusalananda Oct 8 '17 at 14:29
  • getting error: $ touch -d "$(date +%FT00:00:00)" /tmp/midnight touch: illegal option -- d usage: touch [-amc] [-t [[CC]YY]MMDDhhmm[.SS] | -r ref_file] file ... – User123 Oct 8 '17 at 14:50
  • 1
    @User123 What Linux are you running? Are you using busybox? The -d flag is a POSIX standard flag. Oh well, change that line to touch -t "$(date +%Y%m%d0000)" /tmp/midnight. – Kusalananda Oct 8 '17 at 14:55
2

You can use stat(1) to get the modified time of a file, but this is not portable.

On Linux:

$ stat -c %y some_file
2017-09-23 10:24:09.880806666 +0200

$ date -d @$(stat -c %Y some_file) +%d-%m-%Y
23-09-2017

On BSD:

$ stat -f %Sm -t %d-%m-%Y some_file
23-09-2017
1

how to get the files of the current date?

ls command has --time-style option to print the time in specific format:

ls -l --time-style=+'%d-%m-%Y' | awk -v d=$(date +%d-%m-%Y) '$6==d'

--time-style=STYLE
with -l, show times using style STYLE: full-iso, long-iso, iso, locale, or +FORMAT; FORMAT is interpreted like in 'date';

1

With zsh, using glob qualifiers and age:

autoload age
print -rl ./**/XYZ.LOG*(e_'age today now'_)

or, if you prefer the long listing format:

autoload age
ls -lrtd -- **/XYZ.LOG*(e_'age today now'_)
  • Note that it will not list files with mtime in the future but still today, so after whatever now is when you run the command until 00:00:00 tommorow. To get those too remove the argument now. – don_crissti Oct 8 '17 at 15:33
0

In general, parsing ls output is a bad idea. Related: Why not parse ls?


An almost work ls answer

A mostly robust way to get all files of today with GNU ls will be:

ls -lrt --time-style=+'%Y%m%d' * | grep " $(date +'%Y%m%d') "

That makes the date format of each file one field which is robustly selected by the grep with delimiting spaces included (that removes the chance of a file named as a date to be selected (unless it also include the spaces in the name, unlikelly, but still possible).

Of course, if the file name include spaces, the parsing of the output of ls with awk {print $7} will be affected and fail (more fields) (try with a file created as touch ' 20171008 test'.

Use simple (GNU) find

As what was asked was for file(s) of today's date (one day), we can make a selection with find's -mtime (for modification date, or -atime or -ctime for the other two)

$ find . -daystart -type f -mtime -1 -not -mtime -0 -print

The -daystart option ensure that the time interval is from midnight.
a -mtime -1 selects files of a day old (and less, i.e. today).
The -not -mtime -0 rejects files in the future.

Not so simple find

When time in a range (not limited to whole days) is needed, this incantation might help:

find ./ -type f -newermt "$dstart" -not  -newermt "$dend" -print

where dstart and dend contain the start and end time limits:

dstart=$( date -d '20171006 22:10:12' )
dend=$(   date -d '20171008 20:10:12' )
find ./ -type f -newermt "$dstart" -not  -newermt "$dend" -print

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.