As mentioned, it's not advisable to
parse ls. There are other ways to get the most recent file:
How can I get the newest (or oldest) file from a directory?
http://mywiki.wooledge.org/BashFAQ/099
But if you just want to move the last entry of each grouping, as shown by the natural sort order, I think we can make it a bit simpler.
Code:
target='/path/to/newfolder'
#loop through all xlsx files, in alphanumeric order
for i in *.xlsx; do
#sets $last to $i for the first entry, otherwise keeps the original value
last=${last:-$i}
#compare the prefix of the last file with the prefix of the current file
if [[ ! ${last%%_*} == ${i%%_*} ]]; then
#if the two files have different prefixes, move the $last file
mv "$last" "$target"
# save the current file to last
last=$i
done
#finish by moving the final leftover file, which should be the most recent.
mv "$last" "$target"
See
parameter substitution for an explanation of the "${var}" patterns used.
Edit: Here's a much more streamlined solution, using a bash
associative array:
Code:
declare -A files
target='/path/to/newfolder'
for i in *.xlsx; do
files["${i%%_*}"]=$i
done
mv -t "$target" "${files[@]}"
The array is indexed by the file prefix. The loop sets the value of each index entry to each file in turn, so in the end only the final, newest one is stored in the array. Then it just takes a single
mv command to shift them all at once.