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

ここで、過去 2 か月間の既存のファイルをすべて一致させるには、次のようにします。

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

fetchこのファイルに対して実行したいコマンドで置き換えます。)1ヶ月間一致するファイルがない場合、パターンは同じままです。

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"

関連情報