
仕事
毎月ファイルをアーカイブするには、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
私の難しさ
私が経験した主な問題は次のとおりです。
bashでファイル修正日を取得するには?
特定のディレクトリ内のすべてのファイルをどのように処理して適切なアーカイブに保存しますか?
私は問題を解決しようとしています。
ファイルの修正日を見つける2つの方法が見つかり
date -r $ file +% F
ましたfind dir -name filename -printf '% TY-% Tm-% Td \ n'
。これらのどれもコンピュータで実行されません(OS AIX、私はrootではありません)。また、「ls -lc」コマンドが表示する内容がわかりません(修正日がないようです)。私のアイデアは一つだけです。
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ファイルを生成できるように、最後の行()のコメントを外してください。
ファイル名に改行文字が含まれているとこれが中断される可能性がありますが、ログファイルにはこれが問題にならないことを願っています。