You have a loop that tests a certain condition based on two variables that you never change. I'm assuming you were meaning to decrease the NUMSNAPS
value by one in each iteration.
In the zsh
shell, you may do
retain=2
rm -f while/*(DN.Om[retain+1,-1])
to delete all regular files (including files with hidden names) apart from the $retain
most recently modified files. If this happens to be several thousands of files, you may want to use zargs
instead:
retain=2
autoload -U zargs
zargs -- while/*(DN.Om[retain+1,-1]) -- rm
If you want to order the files by name instead, then replace Om
("order by mtime timestamp, in decreasing order") by On
("order by name, in decreasing order").
You could obviously call this from another shell than zsh
by using e.g.
retain=2
zsh -c 'rm -f $2/*(DN.Om[$1+1,-1])' zsh "$retain" "while"
This also passes the name of the directory and the number of files to retain into the in-line script, making it easier to incorporate into an existing non-zsh
script.
In the bash
shell, you don't really want to parse the output of ls
. Instead you may want to use
shopt -s dotglob nullglob
retain=2
set -- while/*
while [ "$#" -gt "$retain" ]; do
rm -f "$1"
shift
done
This would set the list of positional parameters to the list of files in the while
directory (including hidden names), and then remove files form that list until there are only retain
files left in the list.
This avoids issues with awkward filenames, and it also avoids calling ls
once for every file removed.
This code would delete files based on their names (not by last-modified timestamp). This seems to be what your code is also attempting to do.
NUMSNAPS
inside the loop. – kaylum Jan 02 '20 at 23:09