Move files based on date in filename

I know this gets covered quite a bit in the forum and I think there is enough there for me to figure out how to do what I am trying to do, I just don't think I would do it very efficiently so I am going to ask the question...

I have database log files with date and time stamps in the file like
db2diag-2010-04-09-06.04.01.log in a directory in AIX

I want to process this directory of log files and where the date stamp in the file name is greater than 30 days old (I have roughly 6 months worth now) I want to move that file to another path and put it into the appropriate folder based on date where the naming is month-year format (like Apr-2010).

There's probably a thousand ways to think about this and I can only see the one right at the top of my mind, but I am guessing I need a loop where I parse the date out of each file name with pattern db2diag*.log, see if it's more than 30 days old and then use that date to figure out the name of the folder it needs to move to. I think with my knowledge level I'd probably be tempted to do that with a case statement so that when I parse the 04 out of the example file name I do something like (where $month equals 04)

case "$month" in 
1) month=Jan;
;;
2) month=Feb;
;;
3) month=Mar;
;;
4) month=Apr;
;;

.
.
.

ideas?

How about ...

#!/bin/bash

for FILE in $( ls db2diag*.log )
do
  FOLDER=$( echo $FILE | awk -F '-' '{print $2"_"$3}' )
  if [ ! -d $FOLDER ]
  then
    mkdir -v $FOLDER
  fi
  mv -v $FILE $FOLDER
done

exit 0
# finis
[house@leonov] ls db*
db2diag-2010-04-09-06.04.01.log  
db2diag-2010-04-10-06.04.01.log  
db2diag-2010-05-10-06.04.01.log
[house@leonov] bash code.bash
mkdir: created directory `2010_04'
`db2diag-2010-04-09-06.04.01.log' -> `2010_04/db2diag-2010-04-09-06.04.01.log'
`db2diag-2010-04-10-06.04.01.log' -> `2010_04/db2diag-2010-04-10-06.04.01.log'
mkdir: created directory `2010_05'
`db2diag-2010-05-10-06.04.01.log' -> `2010_05/db2diag-2010-05-10-06.04.01.log'
[house@leonov] lr 2010*
2010_04:
db2diag-2010-04-09-06.04.01.log
db2diag-2010-04-10-06.04.01.log
2010_05:
db2diag-2010-05-10-06.04.01.log

Thank you. I'm going to play with this a little and see if I get it tuned to what I need. The month-year (Apr-2010) folders that I am moving to already exist which is why I need to figure out from my file name that *2010-04-09 should go into the Apr-2010 folder as opposed to making a new one. I like your loop logic though so I'm gonna borrow that and see if I can get there. I'll let you know.

No problem :wink:

YEAR=$( echo $FILE | awk -F '-' '{print $2}' )
MONTH=$( echo $FILE | awk -F '-' '{print $3}' )
case $MONTH in
  "01") MONTH='JAN' ;;
  # etc. etc.
  "04") MONTH='APR' ;;
  # etc. etc.
esac
FOLDER=$MONTH"-"$YEAR
1 Like

Okay.... Thank you...actually that's the direction I going in, I just felt like maybe that was too much overhead to do that case compare with each file in the loop. I was thinking there might be a simpler way. Here's what I was going to send back to you...

for FILE in $( ls $instance_hpath/db2dump/db2diag*.log )
do
   FMONTH=$( echo $FILE | awk -F '-' '{print $3}' )
   FYEAR=$( echo $FILE | awk -F '-' '{print $2}' )
   case "$FMONTH" in 
   01) FMONTH=Jan;
   ;;
   02) FMONTH=Feb;
   ;;
   03) FMONTH=Mar;
   ;;
   04) FMONTH=Apr;
   ;;
   05) FMONTH=May;
   ;;
   06) FMONTH=Jun;
   ;;
   07) FMONTH=Jul;
   ;;
   08) FMONTH=Aug;
   ;;
   09) FMONTH=Sep;
   ;;
   10) FMONTH=Oct;
   ;; 
   11) FMONTH=Nov;
   ;;
   12) FMONTH=Dec;
   ;;
   esac
   FOLDER=$FMONTH'_'$FYEAR
   echo $FOLDER
.
.
.
(you'd do your move now)

---------- Post updated at 02:49 PM ---------- Previous update was at 02:45 PM ----------

(Oh...and I still have to work in my Only do this is the file is more than 30 days old logic. I'm guessing I should do an IF statement right up front and make all the rest of this the THEN if the file is > 30 days)

LIST=$( find $instance_hpath/db2dump -name "db2diag*.log" -mtime +30 -print )
for FILE in $LIST
do
  FYEAR=$( echo $FILE | awk -F '-' '{print $2}' )
  FMONTH=$( echo $FILE | awk -F '-' '{print $3}' )
  case $FMONTH in 
    "01") FMONTH=Jan ;;
    "02") FMONTH=Feb ;;
    "03") FMONTH=Mar ;;
    "04") FMONTH=Apr ;;
    "05") FMONTH=May ;;
    "06") FMONTH=Jun ;;
    "07") FMONTH=Jul ;;
    "08") FMONTH=Aug ;;
    "09") FMONTH=Sep ;;
    "10") FMONTH=Oct ;; 
    "11") FMONTH=Nov ;;
    "12") FMONTH=Dec ;;
  esac
  FOLDER=$FMONTH'_'$FYEAR
  mv -v $FILE $FOLDER
done

My goal is to move all but about the current month's worth of files so I ended up trying this...

for FILE in $( ls $instance_hpath/db2dump/db2diag*.log )
do
   FMONTH=$( echo $FILE | awk -F '-' '{print $3}' )
   FYEAR=$( echo $FILE | awk -F '-' '{print $2}' )
   case "$FMONTH" in
   01) FMONTH=Jan;
   ;;
   02) FMONTH=Feb;
   ;;
   03) FMONTH=Mar;
   ;;
   04) FMONTH=Apr;
   ;;
   05) FMONTH=May;
   ;;
   06) FMONTH=Jun;
   ;;
   07) FMONTH=Jul;
   ;;
   08) FMONTH=Aug;
   ;;
   09) FMONTH=Sep;
   ;;
   10) FMONTH=Oct;
   ;;
   11) FMONTH=Nov;
   ;;
   12) FMONTH=Dec;
   ;;
   esac
   if [ $FMONTH != $(date +\%b) ]
   then
   FOLDER=$FMONTH'_'$FYEAR
   echo $FOLDER
   fi 
done

Your approach may be better since it pulls out all the eligible files before the looping starts. Thank you again.

As this is AIX which is hopeless at dealing with long command lines, let's feed the file names one-by-one and ensure that we preserve the filename intact.

find $instance_hpath/db2dump -name "db2diag*.log" -mtime +30 -print | while read FILE
do
  FYEAR=$( echo "${FILE}" | awk -F '-' '{print $2}' )
  FMONTH=$( echo "${FILE}" | awk -F '-' '{print $3}' )
  case $FMONTH in 
    "01") FMONTH=Jan ;;
    "02") FMONTH=Feb ;;
    "03") FMONTH=Mar ;;
    "04") FMONTH=Apr ;;
    "05") FMONTH=May ;;
    "06") FMONTH=Jun ;;
    "07") FMONTH=Jul ;;
    "08") FMONTH=Aug ;;
    "09") FMONTH=Sep ;;
    "10") FMONTH=Oct ;; 
    "11") FMONTH=Nov ;;
    "12") FMONTH=Dec ;;
  esac
  FOLDER=$FMONTH'_'$FYEAR
  mv -v "${FILE}" $FOLDER
done
1 Like