3

I have a directory full of backup folders, with names in the format yyyy-MM-dd--HH:mm:ss

If I enter a date in the same format, is there a way to get the first directory that sorts after it, and copy that folder to somewhere else?

e.g. If my list of backups looks like this:

2019-12-04--16:12:56
2019-12-09--13:36:53
2020-01-23--13:24:13
2020-01-23--13:47:03

and I enter 2020-01-05--00:00:00, I want to restore 2020-01-23--13:24:13

Paulo Tomé
  • 3,782
Tharwen
  • 133

5 Answers5

5
for dir in ????-??-??--??:??:??/; do
    if [[ $dir > "2020-01-05--00:00:00" ]]; then
        printf '%s\n' "$dir"

        # process "$dir" here

        break
    fi
done

The above script will loop through the directories in the current directory whose names matches the pattern ????-??-??--??:??:??.

For each directory, it is compared to the string 2020-01-05--00:00:00. If it sorts after that string lexicographically, the name of the directory is printed and the loop is exited.

This works since the list resulting from a pathname expansion is sorted according to the current collating order (just like ls sorts the list by default).

To copy that directory to elsewhere, replace the comment with something like

rsync -av "$dir" /somewhere/elsewhere

The following is a script that takes the particular string from its first command line argument and does the same thing:

#!/bin/bash

for dir in ????-??-??--??:??:??/; do
    if [[ $dir > "$1" ]]; then
        printf '%s\n' "$dir"

        # process "$dir" here

        break
    fi
done

Testing this with the directories that you list:

$ ls -l
total 10
drwxr-xr-x  2 myself  wheel  512 Jan 24 11:14 2019-12-04--16:12:56
drwxr-xr-x  2 myself  wheel  512 Jan 24 11:14 2019-12-09--13:36:53
drwxr-xr-x  2 myself  wheel  512 Jan 24 11:14 2020-01-23--13:24:13
drwxr-xr-x  2 myself  wheel  512 Jan 24 11:14 2020-01-23--13:47:03
-rw-r--r--  1 myself  wheel  119 Jan 24 11:23 script.sh
$ ./script.sh "2020-01-05--00:00:00"
2020-01-23--13:24:13/
Kusalananda
  • 333,661
  • Could you comment on why it is safe to assume that the glob expansion is performed in lexicographical sort order, and if possible add a link to the respective documentation? – AdminBee Jan 24 '20 at 10:27
  • 1
    @AdminBee - just look at bash man page, LC_COLLATE, "This variable determines the collation order used when sorting the results of pathname expansion, and determines the behavior of range expressions, equivalence classes, and collating sequences within pathname expansion and pattern matching." – steve Jan 24 '20 at 10:34
  • 1
    @AdminBee The result of a pathname expansion is "sorted according to the collating sequence in effect in the current locale". https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13_03 – Kusalananda Jan 24 '20 at 10:36
  • 1
    @steve & Kusalananda thanks for the clarification. – AdminBee Jan 24 '20 at 10:44
  • Thanks, the ???? syntax didn't seem to work for me so I matched the comparison string and the chosen directory against a regex in the end (which also conveniently rejects situations where the input datetime is after the latest datetime in the list) – Tharwen Jan 24 '20 at 14:56
  • 1
    @Tharwen Using ? is standard syntax i filename globbing patterns. If it did not work, then your files have different names that are not matched by that pattern. – Kusalananda Jan 24 '20 at 18:05
4

I came up with

$ printf '%s\n' ????-??-??--??:??:?? | awk '$1 > "2020-01-05--00:00:00"{print;exit}'
2020-01-23--13:24:13
steve
  • 21,892
2

With zsh:

ref=2020-01-05--00:00:00
list=($ref *(DN/oN)) # list is ref + all directories unsorted
list=(${(o)list}) # sort the list (as per locale collation algorithm)
print -r -- ${list[$list[(ie)$ref] + 1]-none}

(where $array[(ie)string] expands to the array index of the element that is exactly string).

0

ls|sort|grep -A 1 2020-01-20|head -n 2|tail -n 1

stoney
  • 1,055
-2

You may try

~$ ls -r | head -n 1
AdminBee
  • 22,803
Yakim
  • 162
  • 2