2

Say you have a parent directory which contains 4 subdirectories. Each subdirectory contains identical contents. Also each subdirectory name is an integer number, the greater the integer number the newer the directory and it's contents

Example:

parentdir/
-> 1/
-> 2/
-> 6/
-> 3/

How do I get the greatest subdirectory as specified in a path such as:

/user/mosawi/parentdir/${NEWEST}/payload.gzip

this would evaluate to: /user/mosawi/parentdir/6/payload.gzip

4 Answers 4

4

You need the newest directory, right? So stop toying with numbers and let zsh do the job:

NEWEST=(/user/mosawi/parentdir/*(/om[1]))
NEWESR=${NEWEST}/payload.gzip

The trick is use glob qualifiers to sort (o) directories (/) on modification time (m) and get only the first one ([1]).

1
  • "So stop toying with numbers and let zsh do the job" favorite quote of the day :) I am limited to bash shell unfortunately.
    – mosawi
    May 7, 2017 at 16:51
3

If the numbers have the same number of digits, the usual sort order should do, so we could just fill an array with the names and take the last element

$ mkdir -p parentdir/{1,2,6,3}
$ A=(parentdir/*)              # fill an array with the names
$ echo "${A[-1]}"              # print the last member of the array
parentdir/6
$ echo "${A[-1]##*/}"          # remove everything up to last / 
6

But if they have different number of digits, that won't work (order would be 1, 13, 2, ...). So let's find the maximum manually:

$ mkdir -p parentdir/{1,2,6,3,13}
$ max=0;                       # assuming they're non-negative integers!
$ for x in parentdir/* ; do 
    n=${x##*/};                # take just the number so that comparisons work 
    [ "$n" -gt "$max" ] && max=$n 
  done
$ echo "$max" 
13

The previous is so much easier that it's worth considering creating the names padded to a fixed length with leading zeroes, if possible.

0
3

mkdir -p parentdir/{1,2,6,3,13}

just ls, without sorting:

ls parentdir/
1  13  2  3  6

now sort:

ls parentdir/ -v
1  2  3  6  13

Now sorting and take the last:

ls parentdir/ -v | tail -n1
13

Pros: no loops, one-liner

Contra: invoke external command

1
  • This is really cleaver, I like it
    – mosawi
    May 7, 2017 at 16:53
1

Assuming that the directory names sort properly (i.e. they contain the same number of digits and there are no non-numerical names in the directory):

newest="$(printf '%s\n' /user/mosawi/parentdir/* | tail -n 1)"

The file will be "$newest/payload.gzip".

Another trick is to create a symbolic link to the latest directory whenever a new directory is created:

mkdir "parentdir/$i" && ln -sf "parentdir/$i" parentdir/latest

It is then easy to access parentdir/latest/payload.gzip.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .