1

I am working in Linux bash.

I have a directory where I have files like this:

  • xpto-10.20.30.tar.xz
  • xpto-10.20.30.tar.xz
  • xpto-20.20.30.tar.xz
  • xpto-30.20.30.tar.xz
  • xpto-10.20.30.tar.xz
  • xpto-40.20.30.tar.xz
  • xpto-40.20.9.tar.xz

I want to get the latest file version name, which should be xpto-40.20.30.tar.xz.

I am using this script:

#!/bin/bash

set_latest () {
  eval "latest=\${$#}"
}
set_latest xpto-*.tar.xz
echo "The highest-numbered file is $latest"

But the result I am getting its xpto-40.20.9.tar.xz

I guess this is because of the number of characters. How can I get the latest file version name (considering this case)? Is there a way as well to get only version "40.30.30"?

H.N.
  • 1,207
  • 2
  • 12
  • 28
  • 1
    If you can use external tools, then how about `ls xpto-*.tar.xz | sort -V | tail -n1`? – rid May 27 '22 at 14:33
  • One more thing, is there a way to return this value outside of the script? I'd like to use the result outside of this script – H.N. May 27 '22 at 16:45

1 Answers1

1

Suggesting:

ls -1 *.tar.xz| sed -E "{s|\.([1-9]\.)|.0\1|;s|\.([1-9]\.)|.0\1|}"  |sort|tail -1|sed -E "s|0([1-9])|\1|g"

In more readable way:

ls -1 *.tar.xz|\
sed -E "{s|\.([1-9]\.)|.0\1|;s|\.([1-9]\.)|.0\1|}"  |\
sort|\
tail -1|\
sed -E "s|0([1-9])|\1|g"

Gradual running

ls -1 *.tar.xz |
ls -1 *.tar.xz |sed -E "{s|\.([1-9]\.)|.0\1|;s|\.([1-9]\.)|.0\1|}" 
ls -1 *.tar.xz |sed -E "{s|\.([1-9]\.)|.0\1|;s|\.([1-9]\.)|.0\1|}"|sort
ls -1 *.tar.xz |sed -E "{s|\.([1-9]\.)|.0\1|;s|\.([1-9]\.)|.0\1|}"|sort|tail -1
ls -1 *.tar.xz |sed -E "{s|\.([1-9]\.)|.0\1|;s|\.([1-9]\.)|.0\1|}"|sort|tail -1|0([1-9])|\1|g"

Explanation

ls -1 *.tar.xz

List all files in current directory with suffix .tar.xz . A file name per line.

sed -E "{s|\.([1-9]\.)|.0\1|;s|\.([1-9]\.)|.0\1|}"

In each file name prefix single digit number with 0

sort

Sort lexicaly all file names

tail -1

Get the last file name

sed -E "s|0([1-9])|\1|g"

Remove 0 prefix from 2 digits numbers in filename

Dudi Boy
  • 4,551
  • 1
  • 15
  • 30