Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Say I have files say like

AA_XX_20111208
AA_XX_20111207
AA_XX_20111206
AA_XX_20111205
AA_XX_20111204
AA_XX_20111203

So using the date part, how can i fetch previous 2 month files ?

For e.g. this month is February, I must fetch all files relating to January and December. and for month of March, i must fetch files of January and February This has to happen each month.

Eg. for month of February i need files of Dec and Jan

AA_XX_20121208
AA_XX_20121207
AA_XX_20121206

...so on

AA_XX_20130108
AA_XX_20130107
AA_XX_20130106

...so on

share|improve this question
    
Use find (1). –  Martin Schröder Feb 6 '13 at 7:38
1  
Is "fetch" supposed to mean something? –  Ignacio Vazquez-Abrams Feb 6 '13 at 7:59

4 Answers 4

Assuming you have GNU date, this function will get you all the dates for the previous 2 months:

dates_in_previous_two_months () { 
    for month_delta in 0 1; do
        # get the last day of a previous month
        day=$(date -d "$(date +%Y-%m-01) -$month_delta month -1 day" +%Y%m%d)
        until [[ $day == *00 ]]; do
            echo $day
            ((day--))
        done
    done
}

For any day in the month of February 2013, this returns:

20130131
20130130
20130129
[... and so on until ...]
20121203
20121202
20121201

In March it will return dates from 20130228 to 20130101

You could use it like:

for date in $(dates_in_previous_two_months); do
    "fetch" AA_XX_$date
done

or

dates_in_previous_two_months | xargs -I{} "fetch" AA_XX_{}
share|improve this answer

You can use find command. The following command will list down all files modified within last 60 days

find . -name 'AA_XX_*' -mtime -60

Here is shell script for achieving what you want, but I would agree that it's not a clean solution. I, myself, don't like this clumsy code, but then it will work for you, for time being

#!/usr/local/bin/bash

YEAR=`date +%Y`
MONTH=`date +%m`
DATE=`date +%d`

if [ $MONTH = 01 ]; then
    OLDEST=`expr $YEAR - 1`11010000
    NEWEST=`expr $YEAR - 1`12312359
elif [ $MONTH = 02 ]; then
    OLDEST=`expr $YEAR - 1`12010000
    echo $YEAR
    NEWEST="$YEAR"01312359
else
    case $MONTH in
            03)
            OLDEST=$YEAR0`expr $MONTH - 2`010000
            if [ $YEAR%4 = 0 ]; then
                    DATE=29
            else
                    DATE=28
            fi
            NEWEST=$YEAR0`expr $MONTH - 1`"$DATE"2359;;

            04|06|09|11)
            OLDEST=$YEAR0`expr $MONTH - 2`010000
            NEWEST=$YEAR0`expr $MONTH - 1`312359;;

            07|08|10|12)
            OLDEST=$YEAR0`expr $MONTH - 2`010000
            NEWEST=$YEAR0`expr $MONTH - 1`302359;;
        esac
fi

echo $OLDEST
echo $NEWEST

touch -t $OLDEST oldest
touch -t $NEWEST newest

find . -name 'AA_XX_*' -newer oldest ! -newer newest > temp.txt
share|improve this answer
1  
Thanks a lot.But i actually need the files by the date part ie. '20130108' ,not by the modified timestamp. –  JK23 Feb 6 '13 at 9:04
1  
But still this command seems very helpful,thanks a lot.Realising only now. –  JK23 Feb 6 '13 at 10:29
    
May I know the reason for the downvotes? If the solution will fail in some cases, I would like to know, so that I can fix it! –  Incognito Feb 7 '13 at 3:48

Like this?

cp source/AA_XX_$(date -d "2 months ago" +%04Y%02m)* source/AA_XX_$(date -d "1 month ago" +%04Y%02m)* destination/
share|improve this answer
1  
That won't work on the 29th, 30th or 31th of March, or more generally any day of the month that has no corresponding day in the month before (or 2 month ago). See the GNU date documentation for a work-around. Note that -d is GNU specific. –  Stéphane Chazelas Feb 6 '13 at 9:55

This month with the year prepended is $(date +%Y%m). Last month is previous_month_1=$(date -d '1 month ago' +%Y%m) with GNU date (i.e. on non-embedded Linux or Cygwin), and the month before is previous_month_2=$(date -d '2 months ago' +%Y%m). on other implementations, they're given by

this_month=$(date +%Y%m)
case $this_month in
  *01) previous_month_1=$((this_month-89)); previous_month_2=$((previous_month-1));;
  *02) previous_month_1=$((this_month-1)); previous_month_2=$((previous_month-89));;
  *) previous_month_1=$((this_month-1)); previous_month_2=$((previous_month-1));;
esac

Now, to match all existing files dated from the previous two months:

fetch "AA_XX_$previous_month_1"?? "AA_XX_$previous_month_2"??

(Replace fetch by the command you want to run on those files.) If a month may have no matching file, the pattern will be left unchanged:

filter_month () {
  case $1 in *'??') return;; esac
  fetch "$@"
}
filter_month "$previous_month_1"??
filter_month "$previous_month_2"??

If you want to fetch all files corresponding to the days of that month, you'll either need some GNU date magic (not described here) or some leap year logic.

filter_month () {
  case $1 in
    *0[13578]|*1[02]) n=31;;
    *0[469]|*11) n=30;;
    *0002) if [ $((${1%????} %4)) -eq 0 ]; then n=29; else n=28; fi;;
    *02) if [ $((${1%??} %4)) -eq 0 ]; then n=29; else n=28; fi;;
  esac
  while [ $n -gt 0 ]; do
    d=$n
    if [ $d -lt 10 ]; then d=0$d; fi
    fetch "AA_XX_$1$d"
  fi
}
filter_month "$previous_month_1"
filter_month "$previous_month_2"
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.