毎月のファイルのアーカイブ

毎月のファイルのアーカイブ

仕事

毎月ファイルをアーカイブするには、bashスクリプトを作成する必要があります。つまり、修正日のあるファイルは2016-12アーカイブに圧縮され2016-12_archive.tar.gz、修正日のあるファイルはアーカイブ2017-01に圧縮される式です。2017-01_archive.tar.gz

例:

FILE NAME   MODIFICATION DATE
file1.log       2016-12-30       ----> 2016-12_archive.tar.gz
file2.log       2016-12-31       ----> 2016-12_archive.tar.gz
file3.log       2017-01-01       ----> 2017-01_archive.tar.gz
file4.log       2017-01-02       ----> 2017-01_archive.tar.gz
file5.log       2017-01-15       ----> 2017-01_archive.tar.gz

私の難しさ

私が経験した主な問題は次のとおりです。

  1. bashでファイル修正日を取得するには?

  2. 特定のディレクトリ内のすべてのファイルをどのように処理して適切なアーカイブに保存しますか?

私は問題を解決しようとしています。

  1. ファイルの修正日を見つける2つの方法が見つかり date -r $ file +% Fましたfind dir -name filename -printf '% TY-% Tm-% Td \ n'。これらのどれもコンピュータで実行されません(OS AIX、私はrootではありません)。また、「ls -lc」コマンドが表示する内容がわかりません(修正日がないようです)。

  2. 私のアイデアは一つだけです。YYYY-MM変更されたすべてのファイル日付をその形式にインポートしてから、一意の値のリストを作成します。次に、このリストの各エントリに対して適切な変更日を含むすべてのファイルを見つけます。

総合的な試み

istat修正日を取得するために使用されます。

$ istat filename
Inode 86741 on device 10/8 File
Protection: rw-r-----
Owner: 6361(user2) Group: 621(norgroup)
Link count: 1 Length 116 bytes

Last updated: 16 февраля 2017 г., 14:25:11 MSK
Last modified: 16 февраля 2017 г., 14:25:11 MSK
Last accessed: 16 февраля 2017 г., 16:08:46 MSK

各ファイルの最後に変更された値を取得する方法は次のとおりです。

for logFile in *.log; do
   mdfDate=$(istat $logFile | grep "Last modified");
   echo $logFile $mdfDate
done

出力:

file1.log Last modified: 30 декабря 2016 г., 14:25:11 MSK
file2.log Last modified: 31 декабря 2016 г., 14:26:11 MSK
file3.log Last modified: 01 января 2017 г., 14:27:11 MSK
file4.log Last modified: 02 января 2017 г., 14:28:11 MSK
file5.log Last modified: 15 января 2017 г., 14:29:11 MSK

したがって、次のステップはUnix形式で日付を抽出することです。

何らかの理由でcut正しく動作しません。Awk重すぎて複雑です。おそらくsed

ベストアンサー1

GNUにアクセスできる場合ははるかに簡単ですdate。実際、より複雑な言語を使用する方が簡単です。たとえば、Perlは次のようになります。

#!/usr/bin/perl -w
use strict;
use POSIX qw(strftime);

my $targetDir = $ARGV[0] || ".";
my %tarFiles;
open(my $input, '-|', "find \"$targetDir\" -type f -name '*.log'");
while (<$input>) {
    # remove trailing newlines
    chomp;
    ## Get the file name
    my $file = $_;
    # Open it as a file handle for stat()
    open(my $fh, '<', "$file") or die;
    # Get the file's stats
    my @stats = stat($fh);
    close($fh);
    # modification time
    my $mtime = $stats[9];
    # Convert to YYYY-MM and build the tar file name
    my $tarfile = strftime "%Y-%m_archive.tar.gz", localtime($mtime);
    # Add to the list of files for this tar file
    push @{$tarFiles{$tarfile}}, qq("$file");
}

for my $tarFile (keys(%tarFiles)) {
    # Build the command that creates the tar file
    my $tarCom = "tar cvzf $tarFile @{$tarFiles{$tarFile}}";
    print "COMMAND: $tarCom\n";

    # Uncomment this line to run the command
    # system("$tarCom")
}                           

スクリプトをmakeTars.plファイル(または目的の場所)に保存して$PATH実行可能にした後(chmod +x /path/to/makeTars.pl)、次のように実行します。

makeTars.pl /path/to/target/dir

たとえば、

$ ls -l
total 0
-rw-r--r-- 1 terdon terdon 0 Dec 30 00:00  file1.log
-rw-r--r-- 1 terdon terdon 0 Dec 31 00:00  file2.log
-rw-r--r-- 1 terdon terdon 0 Jan  1  2016  file3.log
-rw-r--r-- 1 terdon terdon 0 Jan  2  2016  file4.log
-rw-r--r-- 1 terdon terdon 0 Jan  3  2016  file5.log
-rw-r--r-- 1 terdon terdon 0 Jan  3  2016 'file5 with spaces.log'
$ makeTars.pl .
COMMAND: tar cvzf 2017-02_archive.tar.gz "."
COMMAND: tar cvzf 2016-12_archive.tar.gz "./file2.log" "./file1.log"
COMMAND: tar cvzf 2016-01_archive.tar.gz "./file5 with spaces.log" "./file5.log" "./file4.log" "./file3.log"

必要な作業が行われることを確認したら、system("$tarCom")実際にtarファイルを生成できるように、最後の行()のコメントを外してください。

ファイル名に改行文字が含まれているとこれが中断される可能性がありますが、ログファイルにはこれが問題にならないことを願っています。

おすすめ記事