2

I have a directory containing files of the following name structure.

<device>.<yyyy-mm-dd-hh-mm-ss> 

I am working on a script that will retain the the last X copies of these configuration backups per each device. What kind of select magic do I need in order to make this happen?

I was thinking BASH but I'm really language agnostic.

3 Answers 3

1

Wildcards expand file names in lexicographic order. Since your date format matches lexicographic order, your requirement boils down to retaining the last X matches for a wildcard (or all matches if there are fewer than X). I'll assume that your backups are the files matching $device.*, adjust the pattern as needed.

In zsh:

set -- $device.*
if [[ $# -gt $X ]]; then set -- $@{[-$X,-1]}; fi
cp -- $@ /retain/area/

In any Bourne-style shell (ash, bash, ksh, …):

set -- "$device".*
if [ $# -gt $X ]; then shift $(($#-$X)); fi
cp -- "$@" /retain/area

If what you want is in fact to remove older files, you need to act on the first matches but X (or no matches if there are fewer than X).

In zsh:

files=($device.*)
rm -f -- $files[1,-$X-1]

In other shells:

set -- "$device".*
while [ $# -gt $X ]; do
  rm -- "$1"
  shift
done
0

Taking advantage of your file names, and that ls sorts lexically by default:

ls | awk -F . '
    $1 != current_device {
        current_device = $1
        n5[$1] = n4[$1]
        n4[$1] = n3[$1]
        n3[$1] = n2[$1]
        n2[$1] = n1[$1]
        n1[$1] = $0
    }
    END {
        for (device in n1) {
            print n1[device]
            print n2[device]
            print n3[device]
            print n4[device]
            print n5[device]
        }
    }
'

I assume the device names do not contain dots. Results likely won't be sorted

1
  • 2
    That's awfully complicated. Don't parse the output of ls; the shell can list files just fine thanks to globbing. And the awk code is oversized for what it's doing. Commented Feb 17, 2012 at 7:43
0

May need some changes but:

ls <DEVICE>.* | sort -r | tail -n +<X+1> | xargs echo rm 

That will output the rm statement, remove the "echo" to just delete directly.

1

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.