skip to Main Content

I’m using centOS8 and I’m writing a batch script to delete data up to the previous day.

The structure of the folder that needs to be deleted is as follows.

root/data/year/month/day/uuid/time

For example:

root
  └ data
      └ ImportantFolder
      └ 2020
      └ 2021
          └ 11
          └ 12
             └ 1
             └ 2
               └ 550e8400-e29b-41d4-a716-446655440000
                  └ 2243010332.d     

The script runs every day at 2:00 AM and should only delete data up to the previous day.

For example, if today is January 1, 2022, folders up to December 31, 2021 should be removed.

It would be simple to remove only the files created more than a day ago in the data folder, but data that does not follow the year/month/day/.. structure in the data folder(like ImportantFolder above) should not be deleted, and only folder created after midnight should be kept. (The system works 24/7)

So, when the script is executed, I am thinking whether it is possible to get yesterday’s date, decompose day, month, and year, and then delete it through a conditional statement.
I’m new to shellscript so I don’t know if this is possible. Can you help me with a better idea or how I can get and disassemble the previous day with a script?


The script I wrote by referring to the guide in the answer is as follows. It’s a beginner’s script, but I hope it helps someone.

#!/bin/bash

function rm_Ymd_forder(){
  current_year=$(($(date +%Y)))
  current_month=$(($(date +%m)))
  current_day=$(($(date +%d)))
  base_dir=/data

  for current_dir in "$base_dir"/*/; do
    current_dir=$(basename "$current_dir")
    if [ "$current_dir" -lt "$current_year" ];
    then
      rm -rf "$base_dir"/"$current_dir"
      echo "$base_dir"/"$current_dir" "Deleted"
    fi;
  done

  for current_dir2 in "$base_dir"/"$current_year"/*/; do
    current_dir2=$(basename "$current_dir2")
    if [ "$current_dir2" -lt "$current_month" ];
    then
      rm -rf "$base_dir"/"$current_year"/"$current_dir2"
      echo "$base_dir"/"$current_year"/"$currnet_dir2" "Deleted"
    fi;
  done

  for current_dir3 in "$base_dir"/"$current_year"/"$current_month"/*/; do
    current_dir3=$(basename "$current_dir3")
    if [ "$current_dir3" -lt "$current_day" ];
    then
      rm -rf "$base_dir"/"$current_year"/"$current_month"/"$current_dir3"
      echo "$base_dir"/"$current_year"/"$current_month"/"$current_dir3" "Deleted"
    fi;
  done
}

(
  set -e
  rm_Ymd_forder
)

errorCode=$?
if [ $errorCode -ne 0 ]; then
  echo "Error"
  exit $errorCode
else
  echo "OK"
  exit 0
fi

2

Answers


  1. You can try something like this:

    find /root/data -type d -not -name "ImportantFolder" -mtime +1 -exec rm -rf {} ;
    

    So, searching only directories, excluding the "ImportantFolder" (Not tested).

    Login or Signup to reply.
  2. Here are some guidelines for you:

    1. Get the various date segments using GNU date
      • Example: current_year=$(date +%Y) will give you the current year
    2. Use this type of code to loop over the directories, one level at a time
      • Example: for current_dir in /data/*/; do
    3. Get just the directory name for each item (strip off slashes) using basename or string modification
      • Example: current_dir=$(basename "$current_dir")
    4. At each level, check if the number is lower than the current year/month/day (depending on level)
      • Compare using -lt / -gt
      • Example: if [ "$current_dir" -lt "$current_year" ]; then … (remove it – or do some logging to start with to make sure you’re on track)
    5. If the number is equal (-eq) to the current year/month – then you can loop through that next
      • Example: for current_dir2 in /data/"$current_dir"/*/; do
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search