Search code examples
linuxbashscriptingls

Linux clean directory script


I need to write a script for a web server that will clean out files/folders older than 14 days, but keep the last 7 files/directories. I've been doing my research so far and here is what I came up with (I know the syntax and commands are incorrect but just so you get an idea):

ls -ldt /data/deployments/product/website.com/*/ | tail -n +8 | xargs find /data/deployments/product/website.com/ -type f -type d -mtime +14 -exec rm -R {} \;

This is my thought process as to how the script should behave (I'm more a windows batch guy):

List the directory contents

 If contents is less than or equal to 7, goto END
 If contents is > 7 goto CLEAN
:CLEAN
ls -ldt /data/deployments/product/website.com/*/
keep last 7 entries (tail -n +8)
output of that "tail" -> find -type f -type d (both files and directories) -mtime +14 (not older than 14 days) -exec rm -R (delete)

I've seen a bunch of examples, using xargs and sed but I just can't figure out how to put it all together.


Solution

  • #!/bin/bash
    
    find you_dir -mindepth 1 -maxdepth 1 -printf "%T@ %p\n" | \
    sort -nrk1,1 |sed '1,7d' | cut -d' ' -f2 | \
    xargs -n1 -I fname \
    find fname -maxdepth 0 -mtime +14 -exec echo rm -rf {} \;
    

    remove the echo if your happy with the output...

    Explanation (line-by-line):

    1. find in exactly in your_dir and print seconds_since_Unix_epoch (%T@) and file(/dir)name for each file/dir on a separate line
    2. sort by first field (seconds_since_Unix_epoch) descending, throw the first seven lines away - from the rest extract just the name (second field)
    3. xargs passes on to new find process argument-by-argument (-n1) and uses fname to represent argument
    4. -maxdepth 0 limits find to just fname

    You could store the minNrOfFiles and the ageLimit in Bash-Variables or pass in to the script with just few changes:

    minNrOfFiles=7 # or $1
    ageLimit=14    # or $2
    

    change: sed '1,'"$minNrOfFiles"'d' and -mtime +"$ageLimit"