毎月最後のファイルをアーカイブし、残りを削除します。

毎月最後のファイルをアーカイブし、残りを削除します。

次のファイルがあります。 9月30日、10月30日のファイルをアーカイブして残りは削除したいと思います。

-rw-r--r-- 1 nbswmcm advboprd 13463761 Sep  2 01:19 vtm_data_12month_20140902.txt
-rw-r--r-- 1 nbswmcm advboprd 13474125 Sep  3 01:51 vtm_data_12month_20140903.txt
-rw-r--r-- 1 nbswmcm advboprd 13492755 Sep  4 01:57 vtm_data_12month_20140904.txt
-rw-r--r-- 1 nbswmcm advboprd 13499981 Sep  5 01:59 vtm_data_12month_20140905.txt
-rw-r--r-- 1 nbswmcm advboprd 13507296 Sep  7 08:39 vtm_data_12month_20140907.txt
-rw-r--r-- 1 nbswmcm advboprd 13508099 Sep  9 04:02 vtm_data_12month_20140909.txt
-rw-r--r-- 1 nbswmcm advboprd 13508886 Sep 10 01:33 vtm_data_12month_20140910.txt
-rw-r--r-- 1 nbswmcm advboprd 13513056 Sep 11 02:25 vtm_data_12month_20140911.txt
-rw-r--r-- 1 nbswmcm advboprd 13512334 Sep 12 02:36 vtm_data_12month_20140912.txt
-rw-r--r-- 1 nbswmcm advboprd 13512391 Sep 14 08:41 vtm_data_12month_20140914.txt
-rw-r--r-- 1 nbswmcm advboprd 13515984 Sep 16 02:35 vtm_data_12month_20140916.txt
-rw-r--r-- 1 nbswmcm advboprd 13516946 Sep 17 02:27 vtm_data_12month_20140917.txt
-rw-r--r-- 1 nbswmcm advboprd 13523528 Sep 18 02:39 vtm_data_12month_20140918.txt
-rw-r--r-- 1 nbswmcm advboprd 13520200 Sep 19 02:28 vtm_data_12month_20140919.txt
-rw-r--r-- 1 nbswmcm advboprd 13514677 Sep 21 09:33 vtm_data_12month_20140921.txt
-rw-r--r-- 1 nbswmcm advboprd 13518239 Sep 23 02:29 vtm_data_12month_20140923.txt
-rw-r--r-- 1 nbswmcm advboprd 13488002 Sep 24 02:51 vtm_data_12month_20140924.txt
-rw-r--r-- 1 nbswmcm advboprd 13491370 Sep 25 02:38 vtm_data_12month_20140925.txt
-rw-r--r-- 1 nbswmcm advboprd 13414606 Sep 26 02:42 vtm_data_12month_20140926.txt
-rw-r--r-- 1 nbswmcm advboprd 13411621 Sep 28 08:59 vtm_data_12month_20140928.txt
-rw-r--r-- 1 nbswmcm advboprd 13529594 Sep 30 02:52 vtm_data_12month_20140930.txt
-rw-r--r-- 1 nbswmcm advboprd 13520560 Oct  1 02:54 vtm_data_12month_20141001.txt
-rw-r--r-- 1 nbswmcm advboprd 13519613 Oct  2 02:54 vtm_data_12month_20141002.txt
-rw-r--r-- 1 nbswmcm advboprd 13534704 Oct  3 02:19 vtm_data_12month_20141003.txt
-rw-r--r-- 1 nbswmcm advboprd 13545015 Oct  5 08:47 vtm_data_12month_20141005.txt
-rw-r--r-- 1 nbswmcm advboprd 13541506 Oct  7 02:51 vtm_data_12month_20141007.txt
-rw-r--r-- 1 nbswmcm advboprd 13556650 Oct  8 02:31 vtm_data_12month_20141008.txt
-rw-r--r-- 1 nbswmcm advboprd 13551903 Oct  9 02:33 vtm_data_12month_20141009.txt
-rw-r--r-- 1 nbswmcm advboprd 13567484 Oct 10 02:33 vtm_data_12month_20141010.txt
-rw-r--r-- 1 nbswmcm advboprd 13569503 Oct 12 08:40 vtm_data_12month_20141012.txt
-rw-r--r-- 1 nbswmcm advboprd 13567657 Oct 14 02:25 vtm_data_12month_20141014.txt
-rw-r--r-- 1 nbswmcm advboprd 13574132 Oct 15 02:40 vtm_data_12month_20141015.txt
-rw-r--r-- 1 nbswmcm advboprd 13581260 Oct 16 02:50 vtm_data_12month_20141016.txt
-rw-r--r-- 1 nbswmcm advboprd 13585758 Oct 17 02:27 vtm_data_12month_20141017.txt
-rw-r--r-- 1 nbswmcm advboprd 13587851 Oct 19 10:02 vtm_data_12month_20141019.txt
-rw-r--r-- 1 nbswmcm advboprd 13591515 Oct 21 02:43 vtm_data_12month_20141021.txt
-rw-r--r-- 1 nbswmcm advboprd 13602271 Oct 22 02:59 vtm_data_12month_20141022.txt
-rw-r--r-- 1 nbswmcm advboprd 13604358 Oct 23 03:22 vtm_data_12month_20141023.txt
-rw-r--r-- 1 nbswmcm advboprd 13607622 Oct 24 02:52 vtm_data_12month_20141024.txt
-rw-r--r-- 1 nbswmcm advboprd 13605666 Oct 26 10:25 vtm_data_12month_20141026.txt
-rw-r--r-- 1 nbswmcm advboprd 13612303 Oct 28 02:32 vtm_data_12month_20141028.txt
-rw-r--r-- 1 nbswmcm advboprd 13617526 Oct 29 02:49 vtm_data_12month_20141029.txt
-rw-r--r-- 1 nbswmcm advboprd 13627963 Oct 30 02:38 vtm_data_12month_20141030.txt

答え1

GNUシステムでは、特定のファイル名パターンを使用して

ls -r | uniq -w23

それはあなたのために予約されています。したがって、削除することができます:

ls -r | uniq -w23 | xargs mv -t ../to-keep/

そして残りのファイルをすべて削除してください。

23は長さですvtm_data_12month_201409。したがって、uniq同じ 23 文字の長さのプレフィックスを持つファイルのリスト (逆順に並べられたファイルのリスト) の最初のファイルのみが返されます。

一度に完了:

ls -r | awk -F_ 'a[substr($NF,1,6)]++'

削除するファイルが一覧表示されます。

ls -r | awk -F_ 'a[substr($NF,1,6)]++' | xargs rm -f

(ファイル名にスペース、引用符、またはバックスラッシュ文字が含まれていないと仮定)。

_ここでは、最初の23文字を表示するのではなく、最後の文字の後の最初の6文字を表示します。

答え2

logrotateコマンドを使用してください。/var/log日付またはサイズに基づいてログを回転できます。

/etc/cron.daily/logrotateそしてを見てください/etc/logrotate.conf/etc/logrotate.conf回転したいファイルを処理するための項目を入れることができるはずです。

次のウェブサイトも参照してください。http://www.rackspace.com/knowledge_center/article/understanding-logrotate-utility

さらに助けが必要な場合はお知らせください。頑張ります。

さて、私のシステムは/etc/cron.daily/logrotate1日1回logrotateを呼び出します。各ファイルの処理方法を/etc/logrotate.conf教えてください。logrotateしたがって、修正について心配するだけです。/etc/logrotate.conf

そのエントリをファイルに追加するだけです/etc/logrotate.conf

/var/log/LOGFILENAME {
    monthly
    create 0664 root root
    rotate 1
}

その後、システムまたはcronを再起動すると、変更が適用されます。logrotateプロファイルを直接呼び出してテストすることもできます。

/usr/sbin/logrotate /etc/logrotate.conf

この行は前のコピーをアーカイブして、先月と今月の2か月分のログを生成するように指示rotate 1します。logrotate今月のログのみを保存するには、にrotate 1変更してください。rotate 0

答え3

この問題を一般的に解決する必要がありますか、または一度だけ解決する必要がありますか?一度だけ解決する必要がある場合は、単純な解決策が最善です。 Bashで中括弧拡張を使用できます。

rm vtm_data_12month_2014{09,10}{01..29}.txt

これは、次の理由でお客様のケースに適用される場合があります。

  • 送信したいパラメータの数がrmARG_MAXを超える可能性は低いです。
  • 10月と9月にも滞在したい日付が同じです。

この問題をより一般的に解決する必要がある場合は、月ごとに終了する日付が異なることを考慮する必要があります。たとえば、10月は31日に終わりますが、例には30日までのデータのみが含まれます。

例のファイル命名スキームが信頼できる場合、次のコマンドは、毎月利用可能な最新のファイルを除くすべてのファイルを削除します(ファイルの作成または変更に関連する実際のタイムスタンプではなくファイル名に基づいています)。

get_years() {
  find ./ -type f | cut -d'_' -f4 | cut -c1-4 | sort | uniq
}

get_months_for_year() {
  year=$1
  find ./ -iname "vtm_data_12month_${year}*.txt" -type f | cut -d'_' -f4 | cut -c5-6 | sort | uniq
}

get_latest_for_year_month() {
  year=$1
  month=$2
  find ./ -iname "vtm_data_12month_${year}${month}*.txt" -type f | cut -d'_' -f4 | cut -c7-8 | sort | tail -1
}

for year in $(get_years); do
  for month in $(get_months_for_year $year); do
     latest=$(get_latest_for_year_month $year $month)
     end=$(($latest - 1))
     for i in $(seq 1 $end); do 
      day=$(printf '%02d' $i)
      rm vtm_data_12month_${year}${month}${day}.txt
     done
  done
done

DateTimeライブラリを持つbash以外の言語は、よりクリーンで信頼性の高いソリューションを提供できます。ここで提供されている両方のソリューションは、特定の日付のファイルが見つからない場合、エラーが発生します。

答え4

bashスクリプトを使用して日付を検証し、日付範囲を生成するのは難しく、エラーが発生しやすいです。最良の方法は、詳細な検査を可能にするpython他のperl高度なスクリプト言語を使用することです。日付範囲内のファイルを削除し、日付範囲を除外するようにスクリプトを更新しました。

オプションは次のようになります。

範囲内のファイルの削除

./dfile.py --from 20140929 --to 20141001  --range

範囲外のファイルを削除

./dfile.py --from 20140929 --to 20141001  --out-range

プログラムはまた、引数が誤って提供された場合に便利なヘルプメッセージを生成します。

#!/usr/bin/env python3


import os
import sys
import argparse
import datetime

parser = argparse.ArgumentParser()
parser.add_argument('--from', dest="fromd", type=str, required=True, help="From date")
parser.add_argument('--to', dest="tod", type=str, required=True, help="To date")
parser.add_argument('--range', dest='drange', action='store_true', help="Delete files between the given date")
parser.add_argument('--out-range', dest="orange", action='store_true', help="Delete files apart form the given date")

args = parser.parse_args()

if args.drange and args.orange:
    print('Enter either --range or --out-range option')
    sys.exit(1)
elif not (args.drange or args.orange):
    print('You must select either --range or --out-range option')
    sys.exit(1)

from_date = args.fromd
to_date = args.tod
path='/tmp/tmp.54JUy4ZP6x/'


try:
    from_date = datetime.datetime.strptime(from_date, '%Y%m%d').date()
    to_date   = datetime.datetime.strptime(to_date, '%Y%m%d').date()
except ValueError:
    print('Check if the date has been given in YYYYMMDD format')
    sys.exit(1)

files = [ x for x in os.listdir(path) if x.endswith('.txt') ]


for file in files:

    file_date = datetime.datetime.strptime(file[17:25], '%Y%m%d').date()

    if args.orange:
        # Delete files out of date range
        if not from_date < file_date < to_date:
            print('Deleting file {}'.format(file))
            os.remove(path + '/' + file)
    else:
        # Delete files within date range
        if from_date < file_date < to_date:
            print('Deleting file {}'.format(file))
            os.remove(path + '/' + file)

pathプログラムで変更する必要があるパラメーターを除くすべてのパラメーターは構成可能です。

それがあなたに役立つことを願っています。

関連情報