If your filenames don't contain any newlines and your system has GNU stat, you could:
- Use an array variable
filenames
- Use
stat to print the size and filename of each file, then use sort on the result (reverse numeric) and
then remove the first field (the size) with cut to get the filenames ordered by size (largest first).
- Feed the result to a
while loop for further processing.
filenames=( one two three )
while IFS= read -r file; do
echo "do something with $file"
done < <(stat --printf '%s\t%n\n' -- "${filenames[@]}" | sort -nr | cut -f2-)
The same as above, but using the null character as delimiter (if you can't guarantee your filenames won't contain newlines; you'll also need GNU sort and GNU cut):
filenames=( one two three )
while IFS= read -r -d $'\0' file; do
printf 'do something with %s\n' "$file"
done < <(stat --printf '%s\t%n\0' -- "${filenames[@]}" | sort -znr | cut -zf2-)
Note that for filenames of type symlink, it's the size of the link itself (as opposed to that of the file it points to) that is considered. Add the -L option to stat to change that.
Note that it won't work for a file called - as stat interprets it as meaning the file open on stdin. Use ./- instead to work around it.
zshinstead ofbashand formtimeinstead ofsize): How to sort a zsh array by modification date?