Ran
Ran

Reputation: 3523

Linux - Save only recent 10 folders and delete the rest

I have a folder that contains versions of my application, each time I upload a new version a new sub-folder is created for it, the sub-folder name is the current timestamp, here is a printout of the main folder used (ls -l |grep ^d):

drwxrwxr-x 7 root root 4096 2011-03-31 16:18 20110331161649
drwxrwxr-x 7 root root 4096 2011-03-31 16:21 20110331161914
drwxrwxr-x 7 root root 4096 2011-03-31 16:53 20110331165035
drwxrwxr-x 7 root root 4096 2011-03-31 16:59 20110331165712
drwxrwxr-x 7 root root 4096 2011-04-03 20:18 20110403201607
drwxrwxr-x 7 root root 4096 2011-04-03 20:38 20110403203613
drwxrwxr-x 7 root root 4096 2011-04-04 14:39 20110405143725
drwxrwxr-x 7 root root 4096 2011-04-06 15:24 20110406151805
drwxrwxr-x 7 root root 4096 2011-04-06 15:36 20110406153157
drwxrwxr-x 7 root root 4096 2011-04-06 16:02 20110406155913
drwxrwxr-x 7 root root 4096 2011-04-10 21:10 20110410210928
drwxrwxr-x 7 root root 4096 2011-04-10 21:50 20110410214939
drwxrwxr-x 7 root root 4096 2011-04-10 22:15 20110410221414
drwxrwxr-x 7 root root 4096 2011-04-11 22:19 20110411221810
drwxrwxr-x 7 root root 4096 2011-05-01 21:30 20110501212953
drwxrwxr-x 7 root root 4096 2011-05-01 23:02 20110501230121
drwxrwxr-x 7 root root 4096 2011-05-03 21:57 20110503215252
drwxrwxr-x 7 root root 4096 2011-05-06 16:17 20110506161546
drwxrwxr-x 7 root root 4096 2011-05-11 10:00 20110511095709
drwxrwxr-x 7 root root 4096 2011-05-11 10:13 20110511100938
drwxrwxr-x 7 root root 4096 2011-05-12 14:34 20110512143143
drwxrwxr-x 7 root root 4096 2011-05-13 22:13 20110513220824
drwxrwxr-x 7 root root 4096 2011-05-14 22:26 20110514222548
drwxrwxr-x 7 root root 4096 2011-05-14 23:03 20110514230258

I'm looking for a command that will leave the last 10 versions (sub-folders) and deletes the rest.

Any thoughts?

Upvotes: 9

Views: 15745

Answers (7)

Stefan
Stefan

Reputation: 1

I suggest the following sequence. I use a similar approach on my Synology NAS to delete old backups. It doesn't rely on the folder names, instead it uses the last modified time to decide which folders to delete. It also uses zero-termination in order to correctly handle quotes, spaces and newline characters in the folder names:

find /path/to/folder -maxdepth 1 -mindepth 1 -type d -printf '%Ts\t' -print0 \
| sort -rnz \
| tail -n +11 -z \
| cut -f2- -z \
| xargs -0 -r rm -rf

IMPORTANT: This will delete any matching folders! I strongly recommend doing a test run first by replacing the last command xargs -0 -r rm -rf with xargs -0 which will echo the matching folders instead of deleting them.

A short explanation of each step:

  1. find /path/to/folder -maxdepth 1 -mindepth 1 -type d -printf '%Ts\t' -print0

    Find all directories (-type d) directly inside the backup folder (-maxdepth 1) except the backup folder itself (-mindepth 1), print (-printf) the Unix time (%Ts) of the last modification followed by a tab character (\t, used in step 4) and the full file name followed by a null character (-print0).

  2. sort -rnz

    Sort the zero-terminated items (-z) from the previous step using a numerical comparison (-n) and reverse the order (-r). The result is a list of all folders sorted by their last modification time in descending order.

  3. tail -n +11 -z

    Print the last lines (tail) from the previous step starting from line 11 (-n +11) considering each line as zero-terminated (-z). This excludes the newest 10 folders (by modification time) from the remaining steps.

  4. cut -f2- -z

    Cut each line from the second field until the end (-f2-) treating each line as zero-terminaded (-z) to obtain a list containing the full path to each folder older than 10 days.

  5. xargs -r -0 rm -rf

    Take the zero-terminated (-0) items from the previous step (xargs), and, if there are any (-r avoids running the command passed to xargs if there are no nonblank characters), force delete (rm -rf) them.

Upvotes: 0

arx-e
arx-e

Reputation: 71

If the directories' names contain the date one can delete all but the last 10 directories with the default alphabetical sort

ls -d */ | head -n -10  | xargs rm -rf

Upvotes: 2

Thme
Thme

Reputation: 21

ls -dt1 /path/to/folder/*/ | sed '11,$p' | rm -r 

this assumes those are the only directories and no others are present in the working directory.

  • ls -dt1 will normally only print the newest directory however the /*/ will only match directories and print their full paths the 1 ensures one line per match/listing t sorts time with newest at the top.

  • sed takes the 11th line on down to the bottom and prints only those lines, which are then passed to rm.

You can use xargs, but for testing you may wish to remove | rm -r to see if the directories are listed properly first.

Upvotes: 2

Tilo
Tilo

Reputation: 33732

ls -lt | grep ^d | sed -e '1,10d' |  awk '{sub(/.* /, ""); print }' | xargs rm -rf 

Explanation:

  • list all contents of current directory in chronological order (most recent files first)
  • filter out all the directories
  • ignore the 10 first lines / directories
  • use awk to extract the file names from the remaining 'ls -l' output

  • remove the files

Upvotes: 1

linuts
linuts

Reputation: 6748

EDIT:

find . -maxdepth 1 -type d ! -name \\.| sort | tac | sed -e '1,10d' | xargs rm -rf

Upvotes: 0

ahmet alp balkan
ahmet alp balkan

Reputation: 45216

There you go. (edited)

ls -dt */ | tail -n +11 | xargs rm -rf

First list directories recently modified then take all of them except first 10, then send them to rm -rf.

Upvotes: 33

Your directory names are sorted in chronological order, which makes this easy. The list of directories in chronological order is just *, or [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] to be more precise. So you want to delete all but the last 10 of them.

set [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/
while [ $# -gt 10 ]; do
  rm -rf "$1"
  shift
fi

(While there are more than 10 directories left, delete the oldest one.)

Upvotes: -2

Related Questions