Unix - 이름의 날짜 부분을 기반으로 파일을 얻는 방법

Unix - 이름의 날짜 부분을 기반으로 파일을 얻는 방법

다음과 같은 파일이 있다고 합니다.

AA_XX_20111208
AA_XX_20111207
AA_XX_20111206
AA_XX_20111205
AA_XX_20111204
AA_XX_20111203

그렇다면 날짜 부분을 사용하여 이전 2개월의 파일을 어떻게 얻을 수 있습니까?

예를 들어 이번 달은 2월인데 1월과 12월에 관련된 파일을 모두 가져와야 합니다. 3월에는 1월과 2월의 파일을 가져와야 하며 이는 매달 발생해야 합니다.

예를 들어. 2월에는 12월과 1월에 대한 파일이 필요합니다.

AA_XX_20121208
AA_XX_20121207
AA_XX_20121206

...곧

AA_XX_20130108
AA_XX_20130107
AA_XX_20130106

...곧

답변1

GNU 날짜가 있다고 가정하면 이 함수는 지난 2개월 동안의 모든 날짜를 제공합니다.

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
}

2013년 2월의 특정 날짜에 대해 다음이 반환됩니다.

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

201302283월은 에서 까지 의 날짜로 반환됩니다 .20130101

다음과 같이 사용할 수 있습니다.

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

또는

dates_in_previous_two_months | xargs -I{} "fetch" AA_XX_{}

답변2

find명령을 사용할 수 있습니다 . 다음 명령은 지난 60일 동안 수정된 모든 파일을 나열합니다.

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

다음은 원하는 것을 달성하기 위한 쉘 스크립트이지만 이것이 깨끗한 솔루션이 아니라는 데 동의합니다. 나는 개인적으로 이 서투른 코드를 좋아하지 않지만 당분간은 괜찮을 것입니다.

#!/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

답변3

이와 같이?

cp source/AA_XX_$(date -d "2 months ago" +%04Y%02m)* source/AA_XX_$(date -d "1 month ago" +%04Y%02m)* destination/

답변4

이번 달과 연도는 입니다 $(date +%Y%m). 지난 달은 previous_month_1=$(date -d '1 month ago' +%Y%m)GNU 날짜(즉, 내장되지 않은 Linux 또는 Cygwin의 경우)이고 previous_month_2=$(date -d '2 months ago' +%Y%m)다른 구현에서는 다음과 같이 제공됩니다.

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

이제 지난 두 달 동안의 모든 기존 파일을 일치시키려면 다음을 수행하십시오.

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

( fetch이 파일에 대해 실행하려는 명령으로 바꾸십시오.) 한 달 동안 일치하는 파일이 없을 경우 패턴은 동일하게 유지됩니다.

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

해당 월의 날짜에 해당하는 모든 파일을 얻으려면 GNU 날짜 매직(여기서는 설명되지 않음)이나 윤년 논리가 필요합니다.

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"

관련 정보