You've a check for $BASH_VERSION
being (un)set which, to me, suggests you might be considering running this script under sh
rather than bash
. To that end we can omit nullglob
because the code needs to check for this case anyway.
n=10 # Process no more than this number of files
k=0
for f in *
do
[ -f "$f" ] || continue
k=$((k+1))
# Do stuff with your files as "$f"
:
[ $k -ge $n ] && break
done
echo "Files processed: $k"
You can make a couple of small changes if you're going to be using just bash
- use
[[ ... ]]
instead of [ ... ]
- replace
k=$((k+1))
with ((k++))
Notice I've double-quoted my string variable everywhere I've used it. This protects its value from being parsed by the shell and split into words on whitespace. (In general, it's better to double-quote variables when you use them.)
I've re-read your question and realised you want the N most recently modified files. If you were using GNU tools I would use them to generate the list of files safely, but you have not specified these so I've resorted to piping from ls
. In general this is not good practice, mainly because file names can contain non-printing characters and even newlines, but I don't know of a better non-GNU solution without dropping into zsh
.
n=10 # Process no more than this number of files
k=0
ls -t |
while IFS= read -r f
do
[ -f "$f" ] || continue
k=$((k+1))
# Do stuff with your files as "$f"
:
[ $k -ge $n ] && break
done
With GNU tools I'd use this somewhat convoluted pipeline
find -maxdepth 1 -type f -printf "%T@\t%p\0" | # Prefix numeric timestamp
sort -z -k1,2rn | # Sort by the timestamp
cut -z -f2- | # Discard the timestamp
head -z -n$n | # Keep only the top N files
while IFS= read -r -d '' f
do
# Do stuff with your files as "$f"
:
done
bash
version? (output ofbash --version
) – Inian Jun 19 '20 at 09:02bash
or should it besh
compatible too? Are you running on Linux with GNU tools, or some other platform? – Chris Davies Jun 19 '20 at 09:31