Shell – How to delete files from a folder which have more than 60 files in unix

file managementkshshell-script

I want to put a script in cronjob which will run in a particular time and if the file count is more than 60, it will delete oldest files from that folder. Last In First Out.
I have tried,

#!/bin/ksh  
for dir in /home/DABA_BACKUP  
do  
    cd $dir  
    count_files=`ls -lrt | wc -l`   
    if [ $count_files -gt 60 ];  
    then  
        todelete=$(($count_files-60))  
        for part in `ls -1rt`  
        do  
            if [ $todelete -gt 0 ]  
            then  
                rm -rf $part  
                todelete=$(($todelete-1))  
            fi  
        done  
    fi
done   

These are all backup files which are saved daily and named backup_$date.
Is this ok?

Best Answer

No, for one thing it will break on filenames containing newlines. It is also more complex than necessary and has all the dangers of parsing ls.

A better version would be (using GNU tools):

#!/bin/ksh  
for dir in /home/DABA_BACKUP/*
do
    ## Get the file names and sort them by their
    ## modification time
    files=( "$dir"/* );
    ## Are there more than 60?
    extras=$(( ${#files[@]} - 60 ))
    if [ "$extras" -gt 0 ]
    then
    ## If there are more than 60, remove the first
    ## files until only 60 are left. We use ls to sort
    ## by modification date and get the inodes only and
    ## pass the inodes to GNU find which deletes them
    find dir1/ -maxdepth 1 \( -inum 0 $(\ls -1iqtr dir1/ | grep -o '^ *[0-9]*' | 
        head -n "$extras" | sed 's/^/-o -inum /;' ) \) -delete
    fi
done

Note that this assumes that all files are on the same filesystem and can give unexpected results (such as deleting wrong files) if they are not. It also won't work well if there are multiple hardlinks pointing to the same inode.

Related Question