With zsh, use the ${array:#pattern} parameter expansion operator:
$ set foo -D -D bar '' $'a\nb'
$ printf '<%s>\n' "${@:#-D}"
<foo>
<bar>
<>
<a
b>
POSIXly:
for i do
[ "$i" = -D ] || set -- "$@" "$i"
shift
done
printf '<%s>\n' "$@"
BTW, you forgot the quotes, -- and -d:
ls -ld -- "$@"
If you want to sort by modification time, you can just use the -t option, here with -r (reverse) for oldest first:
ls -lrtd -- "$@"
Beware that if $ARGS is an empty array, it will list .. So you can do:
[ "$@" -eq 0 ] || ls -lrtd -- "$@"
To sort reliably based on the hour of the day irrespective of date, with zsh and a ls implementation that supports -U for not sorting:
zmodload zsh/stat # best in ~/.zshrc
bytime() zstat -LA REPLY -F%T +mtime -- $REPLY
ls --full-time -ldU -- .(e{'reply=("$@")'}o+bytime)
With limited shells like bash, it's very hard to sort files based on arbitrary metadata like that. Again, if you've got access to recent GNU tools, it's slightly easier:
[ "$#" -gt 0 ] && (
export LC_ALL=C
printf '%s\0' "$@" |
sed -z 's|^-$|./-|' |
xargs -r0 stat --printf '%y\t%n\0' -- |
sort -zk2,2 |
cut -zf 2-
) | xargs -r0 ls -lUd --
Portably (but still using the non-standard ls -U here), it's generally easier to resort to perl, like:
perl -MPOSIX -e '
exec qw{ls -ldU --},
map {$_->[1]}
sort {$a->[0] cmp $b->[0]}
map {[strftime("%T", localtime((lstat$_)[9])), $_]}
@ARGV' -- "$@"