POSIX has this to say about dates in an ls
-l
ong listing:
The <date and time>
field shall contain the appropriate date and timestamp of when the file was last modified. In the POSIX locale, the field shall be the equivalent of the output of the following date command:
date "+%b %e %H:%M"
...if the file has been modified in the last six months, or:
date "+%b %e %Y"
Taking this into consideration, and ensuring that if there are any newlines in a filename they are properly globbed with the also POSIX specified ls -q
option, it is relatively easy to prepare a regex for an ls
result without find
at all:
d=$(date "+%b %e") y=$(date --date=yesterday "+%b %e")
echo "$d" "$y"
###OUTPUT###
Jul 5 Jul 4
grep
for that and you will return only lines that contain the strings representing either today's or yesterday's dates. The following command adds to that a little:
ls -alRcq | sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"
ls
options consist of:
-a
return all files in a directory - including those that begin with a .dot
-l
long listing
-R
recursively list all child directories
-c
display modification time rather than access time
-q
return the shell glob ?
rather than non-printable or \t
ab characters in a filename
Those results are passed over the |pipe
file to sed
which matches only:
- The blank line preceding a pathname and the following line
- Lines beginning with
-
(in other words - not d
for directory) that also contain your date
.
- It does not print the pathname lines though unless the directory they name actually contains files you've filtered for.
The output looks like this:
ls -alRcq --color=always |
sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"
###OUTPUT###
.:
-rw------- 1 mikeserv mikeserv 2086 Jul 4 10:52 .bash_history
-rw------- 1 mikeserv mikeserv 2657 Jul 4 15:20 .lesshst
-rw-r--r-- 1 mikeserv mikeserv 681 Jul 5 05:18 .zdirs
-rw------- 1 mikeserv mikeserv 750583 Jul 5 08:28 .zsh_history
-rw-r--r-- 1 mikeserv mikeserv 166 Jul 4 23:02 Terminology.log
-rw-r--r-- 1 mikeserv mikeserv 433568 Jul 4 13:34 shot-2014-06-22_17-10-16.jpg
-rw-r--r-- 1 mikeserv mikeserv 445192 Jul 4 13:34 shot-2014-06-22_17-11-06.jpg
./.cache/efreet:
-rw------- 1 mikeserv mikeserv 37325 Jul 4 22:51 desktop_localhost_C.eet
-rw------- 1 mikeserv mikeserv 37325 Jul 4 23:30 desktop_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv 24090 Jul 4 22:51 desktop_util_localhost_C.eet
-rw------- 1 mikeserv mikeserv 24090 Jul 4 23:30 desktop_util_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv 16037 Jul 4 23:30 icon_themes_localhost.eet
-rw------- 1 mikeserv mikeserv 3117 Jul 4 23:30 icons___efreet_fallback_localhost.eet
-rw------- 1 mikeserv mikeserv 768039 Jul 4 23:30 icons_gnome_localhost.eet
-rw------- 1 mikeserv mikeserv 18589 Jul 4 23:30 icons_hicolor_localhost.eet
./.config:
-rw-r--r-- 1 mikeserv mikeserv 30 Jul 4 19:10 pavucontrol.ini
./.config/chrome:
-rw-r--r-- 1 mikeserv mikeserv 94332179 Jul 4 13:36 conf.tar.lz4.bak
Yes, it even works with LS_COLORS
- which is probably a low priority for your cron
of course, but, hey your options are open.
In any case this offers some significant advantages over some other possible solutions.
In the first place find
+ ls
involves multiple invocations - this only involves a single ls
process, and this is why it is able to reliably sort everything - which it does by default - and so sort
is also made ancillary.
Any solution involving find
and sort
and ls
is pretty much doing all of the work twice. ls
and find
will both resolve every pathname and stat
every file. ls
and sort
will both sort all of the results. It is probably best instead to just use the single ls
.
Then of course there's the date
and sed
portions of this answer. What's important to note about that is you do the hard part and get the regex first - and only once - and afterward you only prune a single list of results rather than say, get results, get results, sort results and sort results.
This does not break on filenames containing newlines, as other solutions likely will. This solution does have its own caveats - which I explain next - but they are minute and easily handled. In my opinion, this is the most robust solution here.
There are two cases in which the above command might cause you problems. The first involves the ?
globs in the filenames - while as is it is already a more robust solution than any other offered here, and the likelihood that you will encounter a ?
at all is small enough on its own, there is a possibility that resolving those globs could match more than one filename. Please see this for more information on this subject.
The other possibility involves a false positive - for instance if you have a filename actually matching the date
string for which we are searching with grep
but that was not actually modified on either of those days. I am not counting on that being an issue, but, if it is, ask about it and I can probably help you make the regex more specific in order to handle this.
ls -ls **/*(.)
ls
would sort.