Help on a fairly complicated shell script

Hello,

also with the help of some great users of this forum, I have created following shell script.

MM=120
GG=5000

# get size of directory
szm=$(du -s --block-size M  ./192.168.1.xxx | awk '{print int($0)}')
data=$(date --rfc-3339=seconds)

if [ $szm -ge $GG ] ; then  # too big delete older files

        find ./192.168.1.199 -type f -mmin +$MM -delete
        find ./192.168.1.199 -mindepth 1 -depth -type d -empty -delete

fi

Its purpose is to keep the size of the directory 192.168.1.xxx (where my network video recorders uploads the backup snapshot of the recordings) lower than a given value, i.e. GG oder 5000 mb.

This shell script is executed every hour by a cron.

What I would like to do is to change the script and make it delete xx amount of files (in terms of minutes or if not possible of mb) starting from the oldest ones.

Can anyone please help me?

Thank you so much.
Daniele

You could try this:

MM=120
GG=5000
XX=20

# get size of directory
szm=$(du -s --block-size M  ./192.168.1.xxx | awk '{print int($0)}')
data=$(date --rfc-3339=seconds)

if [ $szm -ge $GG ] ; then  # too big delete older files

    find ./192.168.1.199 -type f -mmin +$MM -printf "%T@ %h/%f\\n" |
        sort -rn | head -$XX | sed 's/^[^ ]* //' |
        xargs --no-run-if-empty -d\\n rm
    find ./192.168.1.199 -mindepth 1 -depth -type d -empty -delete

fi

Here we have find print out the epoch modification time and file path like this:

1494273484.0000000000 ./192.168.1.199/Images/A42301
1494273404.0000000000 ./192.168.1.199/Images/A42310
1494273430.0000000000 ./192.168.1.199/Images/A42317
1494273416.0000000000 ./192.168.1.199/Images/A42322
1494273397.0000000000 ./192.168.1.199/Images/A42336
1494273261.0000000000 ./192.168.1.199/Images/A42344

Then sort on first column with numeric and descending to get oldest files first.
We then pass this to use head to select oldest $XX files, sed to cut off the epoch time and xargs to pass them to the rm command.

2 Likes

Do I read that correctly that the oldest files' sizes should sum up to $GG, and, when below, be deleted? Try (shamelessky stolen from Chubler_XL):

find . -type f -mmin +$MM -printf "%T@ %s %h/%f\\n" | sort -n | awk -vMXSZ=$GG '
(TOTSZ+=$2) < MXSZ      {print "rm -i", $3
                         next
                        }
                        {exit
                        }

If happy with the result, pipe it through sh !

1 Like

Thanks for the kind replies.

It is a bit different, maybe I have been not 100% clear. Sorry.

I need to identify the oldest xx mb of files (or the oldest xx files if it is not possible to identity the oldest xx mb of files) inside the directory 192.168.xxx and then delete them.

Can you please recheck your suggestions?
Thanks

So - what in your new specification is not satisfied by the proposal in post#3?

Thanks for replying.
I apologize, being a newbie I understand slowly.
You wrote "the oldest files' sizes should sum up to $GG, and, when below, be deleted?".

Actually every time I launch the script, it has to remove the oldest xx mb of files.

You wrote "when below, be deleted".

This is what I do not understand.
Thanks

The script takes a list of files by modification date, oldest first, sums up their sizes, and prints them together with the rm command to stdout. If the $GG value is exceeded, the printed list stops.

Did you run the script? Does the output satisfy your request? If yes, pipe it through sh to actually perform the deletions.

I will try it tonight at home (now I am already in the office, Italy) and I will let you know.

In the meanwhile thank you so much.

---------- Post updated at 01:11 PM ---------- Previous update was at 02:13 AM ----------

Hello,
I am testing the script.

In my current version, I delete all files oder than $MM.
Now I need to start the deletion from the oldest file in the path/directory and the deletion should stop either when I delete $MM minutes of files in total or $GG mb of files in total (starting from the oldest one) whatever is easier to implement.

Can you please check it? I apologize if I have not been very clear.

Thanks,
daniele

Thanks for helping,
daniele

The closing ' is missing, at the end of the embedded awk script.
I wonder if you can simply do

find . -type f -mmin +$MM -printf "%T@ %s %h/%f\\n" |
 sort -n | 
 awk -vMXSZ=$GG '(TOTSZ+=$2) >= MXSZ { exit } { print "rm -i", $3 }'
2 Likes

It works!
How can I "pipe through sh"? Shall I replace print with sh?

Thanks,
daniele

.....
{exit}' | sh
1 Like