Assuming you want to pick the ones from Saturdays and that you're on a GNU system, you could do:
ls {path} |
tr .- '- ' |
LC_ALL=C date -uf - '+%A %Y.%m.%d-%H%M' |
grep -Po '^Saturday \K.*-1700'
With zsh
(and on any system), you could do the same using a glob qualifier function:
zmodload zsh/datetime
On{Mon,Tue,Wed,Thu,Fru,Sat,Sun} () {
local t
TZ=UTC0 strftime -rs t %Y.%m.%d-%H%M $REPLY:t &&
TZ=UTC0 LC_ALL=C strftime -s t %a $t &&
[[ $0 = On$t ]]
}
and then:
print -rC1 -- <1900-2100>.<1-12>.<1-31>-1700(N+OnSat)
For the ones on Saturdays.
On your sample, they give:
2022.01.15-1700
2022.01.22-1700
2022.01.29-1700
2022.02.12-1700
2022.02.19-1700
2022.04.16-1700
2022.04.23-1700
2022.05.14-1700
2022.05.21-1700
2022.05.28-1700
You'll notice that there are some gaps, as there's not one file for every Saturday.
To get one per week (the latest of each week), where weeks run from Sunday to Saturday, you could do:
ls -r {path} |
tr .- '- ' |
date -uf - '+%Y%U %Y.%m.%d-%H%M' |
uniq -w6 |
cut -d' ' -f2
Which on your sample gives:
2022.05.30-1700
2022.05.28-1700
2022.05.21-1700
2022.05.14-1700
2022.05.02-1700
2022.04.26-1700
2022.04.23-1700
2022.04.16-1700
2022.02.25-1700
2022.02.19-1700
2022.02.12-1700
2022.01.29-1700
2022.01.22-1700
2022.01.15-1700
(not all being on Saturdays).
For weeks running from Monday to Sunday, replace %Y%U
with %G%V
(the ISO week year and number). That one would also work correctly around changes of years as the %G
and %V
only change between the 31st of December and the 1st of January if the 31st is a Sunday while %Y%U
gives 202152
on Friday 2021-12-31 and 202200
on Saturday 2022-01-01 for instance.
Those are the only two options with %
formatting sequences supported by date
. For weeks starting on different days we'd need to be take a different approach.
For example, we could use the epoch time for the corresponding date interpreted as UTC, divided by the number of seconds in a week, properly offset for the required first day of the week which would also avoid problems around the first day of the year.
For instance, for weeks starting on Sunday:
ls -r {path} |
tr .- '- ' |
date -uf - '+%s %Y.%m.%d-%H%M' |
awk '{week = int(($1 / 86400 - 3)/ 7)}
week != last {print $2}
{last = week}'
Replace - 3
with - 4
for weeks starting on Monday, or - 2
for weeks starting on Saturday.
Or with zsh
:
zmodload zsh/datetime
typeset -A latest=()
for f (<1900-2100>.<1-12>.<1-31>-1700(N))
TZ=UTC0 strftime -rs t %Y.%m.%d-%H%M $f &&
latest[$(( (t / 86400 - 3) / 7 ))]=$f
print -roC1 -- $latest
2022.05.07-1700
is among your expected output, but it's not in your input.touch -r
), then find the next file that is at least 7 days newer than the first one. Then repeat until there are no more files left. That procedure is assuming that a file like2022.01.15-1700
was actually created at 17:00 on January 15th 2022, of course; actually it would work with any name then.