I want to iterate over
for f in $(ls -t foo.*); do ...
Iterating over ls output is fragile. Use globs. [SC2045]
for f in foo.log foo.[[:digit:]].gz foo.[[:digit:]][[:digit:]].gz; do ...
A glob pattern is not a regular expression. See glob(7) for the syntax.
There is no glob pattern to match a series of digits. You can get close with
foo.[0-9]*.gz. If that picks up some names you don't want, you can filter them out with a regex, maybe something like:
echo foo.[0-9]*.* | tr ' ' \\n | grep -E '[.][0-9]+([.]gz)?$'
You can probably use a glob pattern and rely on the shell for ordering, given the constraints you presented. You can check if your shell renders filenames for a glob pattern in sorted order with sort:
echo foo.[0-9]*.gz | tr \ \\n | sort -c
But it's also OK to parse the output of
ls -t unless you're being extremely rigorous. The guidance from
shellcheck is good advice: many people seem to want to parse
ls output when a simple glob would do, and to depend on
ls to behave the same way across different systems is to invite error. That said, you're only asking for
ls to sort the filenames by time, producing a single column of output. Anything else you might do would be more error-prone.