5

In a directory, I have the following files:

myfile_v01.txt
myfile_v02.txt
myfile_v03.txt

How to make a bash script that detects the value of the last version and put the filename of this last version into a variable?

14

Not very refined but seems functional:

var=$(ls | sort -V | tail -n 1)

Then you have the last file stored in $var

2
  • 2
    fyi: Why you shouldn't parse the output of ls(1) : mywiki.wooledge.org/ParsingLs – MarZab Apr 4 '15 at 14:46
  • @MarZab Yes, you're right. I've seen that article already and it does have some valid points. – Erathiel Apr 7 '15 at 10:56
5

There are two obvious approaches, you can either parse the file name or look for the latest file:

  1. Parse the file name, this assumes all files are named as in your example:

    $ latest=myfile_v$(
        for f in myfile_v*; do 
          ver=${f##myfile_v}; ver=${ver%.txt}; echo $ver; 
        done | sort -n | tail -n 1).txt
    
  2. Get the newest file (assuming relatively sane file names that don't contain newlines)

    $ latest=$(ls -tr | tail -n 1)
    
2
  • what does -tr option do ? – Ashildr Dec 12 '13 at 17:12
  • @Ash it sorts by time (-t) in reverse order (-r) so the last file is the newest – terdon Dec 12 '13 at 17:13
4

Here is a solution which uses globbing (so does not rely on parsing ls), like terdon's first solution, but doesn't need to iterate over all files:

myfiles=(myfile_v*)
lastfile="${myfiles[${#myfiles[@]}-1]}"
unset myfiles

First, all matching files are read into an array. Then, the last element of the array gets assigned to $lastfile. Finally, the array isn't needed anymore, so it can be deleted.

Unfortunately, bash (at least to my knowledge) doesn't support sorting the result from globbing#, so this example works fine with you given naming scheme (exactly two digits, also for versions < 10), but will fail for myfile_v1.txt, myfile_v2.txt, ..., myfile_v10.txt.


# zsh (of course ;)) does, so zsh% myfiles=(myfile_v*(n)); lastfile="${myfiles[-1]}"; unset myfiles wouldn't suffer from this limitation.

0

I used a combination of terdon (see above) approaches:

$ latest=$(ls | sort -n | tail -n 1)

My setting: all files are in the same folder, and there are no other files there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.