Finding the second highest version using bash array script and clean up files The goal is to print the highest version and second highest version of the list of files. The version is based on the first three digit places of the version. For example, version 2.3.0.1 version is just 2.3.0 (ignoring the last digit).

Once it can print the highest version and the second highest version of the list, it should remove all other versions which will essentially clean up the folders in that location by only keeping the current and last version.

The EXAMPLE folders that I created are:


AAA_6.6.4.12.TEST
AAA_7.6.4.12.TEST
AAA_75.6.4.12.TEST
AAA_75.7.4.12.TEST
CCC_81.0.0.0.TEST
CCC_81.2.0.0.TEST
CCC_81.2.3.0.TEST
DDD_1.0.0.0.TEST
DDD_1.0.0.1.TEST
DDD_1.0.0.6.TEST
DDD_1.1.0.0.TEST
DDD_2.0.0.0.TEST
DDD_2.0.0.1.TEST
DDD_2.0.0.3.TEST
DDD_3.0.0.0.TEST



This is the array that I have to compute the highest and second highest version:

new_var=( $(for arr in "${var[@]}" 
do
    echo $arr
done | sort) )

for folder in * 
do 
    if [[ $folder =~ ([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.[0-9]{1,3} ]]
    then
        if [[ "$new_var" &lt; "${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.${BASH_REMATCH[3]}" ]]
        then
            new_var="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.${BASH_REMATCH[3]}"
        fi
    else
        echo "failed"
    fi

done;

echo "The highest version is: $new_var"
echo "The second highest version is: ${new_var[-2]}"


This prints the highest version correctly. However, I don't know how to get the second highest version and I don't know how to go about removing the rest of the versions from the directory.
I think your approach is too complicated and esoteric with the use of BASH_REMATCH. Here goes my solution:

versions_to_keep=(
    $(find -maxdepth 1 ! -path . -type d -printf "%f\n"\
        | sort -n -t '_' -k 2 | sort -n -m -t '.' -k 2,3 | tail -n 2)
)
highest_version=${versions_to_keep[-1]}
second_highest_version=${versions_to_keep[-2]}
echo "The highest version is: ${highest_version:?}"
echo "The second highest version is: ${second_highest_version:?}"
find -maxdepth 1 ! -path . -type d ! -name "${highest_version}"\
    ! -name "${second_highest_version}" -exec rm -rf {} +


Explanation:


find -maxdepth 1 ! -path . -type d -printf "%f\n": find and print the basename of directories at most one level below and excluding the current directory .
sort -n -t '_' -k 2: sort in numerical order by field 2, fields delimited by _
sort -n -m -t '.' -k 2,3: sort in numerical order by fields 2 to 3, fields delimited by ., but take care to merge already sorted results
tail -n 2: output the last 2 lines
${highest_version:?} and ${second_highest_version:?}: if either of those variables is null or unset, print an error message and abort the script
find -maxdepth 1 ! -path . -type d ! -name "${highest_version}" ! -name "${second_highest_version}" -exec rm -rf {} +: find directories at most one level below the current directory whose basename patterns match neither ${highest_version} nor ${second_highest_version} and delete them


Actually, if you can guarantee the directory names are of the format XXX_a.b.c.d.TEST, you can combine the two sort into one:
sort -n -t '.' -k 1.5,3, which starts the sort at character position 5 in field 1 and ends the sort at field 3. If you only want to delete empty directories, you can replace -exec rm -rf {} + with -delete.