With GNU date
, you can do:
quadrant=$(( $(date -r "$file" +'(%-m - 1) / 3 + 1') ))
To get the quadrant in which a file was last modified.
In zsh
, you could add a byquadrant
glob sort order as:
zmodload zsh/stat
byquadrant() {
local month
stat -A month -F %-m +mtime -- ${1-$REPLY}
REPLY=$(( (month - 1) / 3 + 1 ))-$REPLY
}
To use as:
ls -ldU -- *(o+byquadrant)
for instance (here using GNU ls
's -U
to disable ls
's own sorting) to sort by quadrant, and then by filename within the same quadrant.
The byquadrant
function returns a string that is made of the quadrant number followed by -
and the original file name, and that's what we tell zsh to o
rder that glob om using the o+<functionname>
glob qualifier.
For symlinks, zsh
's stat
(like GNU date -r
) by default retrieves the mtime of the target of the symlink. Add -L
if you want the mtime of the symlink itself.
If you wanted to use the GNU implementation of stat
(which postdates zsh
's by a few years and is incompatible, and even incompatible with GNU find
's -printf
which predates it by decades and is much less usable), you'd need to output it in one of the two timestamp formats it support (iso8601 or raw epoch time) and extract the month some other way.
Could be for instance with GNU date
again:
quadrant=$(( $(
set -o pipefail
stat -c%y -- "$file" | date -f - +'(%-m - 1) / 3 + 1'
) ))
Note that GNU stat
by default gets you the mtime of the symlink instead of its target (the opposite of zsh
stat
). -L
to change it.
It also doesn't work for a file called -
.
With recent versions of GNU stat
on recent versions of Linux, you can also use %w
instead of %y
to get the birth time of the file where available (as displayed with recent versions of GNU ls
with ls -l --time=birth
), though I find it's less useful as a creation time than the last modification time (which can be seen as the creation time of the contents of the file).
[10-12]
is equivalent to[0-12]
. It matches a single character, in this case0
,1
,2
or any character between0
and1
in the current locale. Usually0
directly precedes1
, so the whole expression is equivalent to[012]
and matches0
,1
or2
only. You probably want1[0-2]
or straightforward10|11|12
. – Kamil Maciorowski Aug 30 '21 at 14:06