Perlサンプル16 FTPのファイル日時判定
投稿:2020-01-29
FTPのリモートファイルの更新日時を基に、DateTimeオブジェクトを生成します。
Perlスクリプトの中でNet::FTPSSLを使いリモートファイルの情報を取得すると、更新日時がファイル毎に異なる書式で戻ります。
なお、このサンプルではNet::FTPSSLを呼ばずファイル情報の文字列だけを用意して日時を設定します。
Net::FTPSSL - A FTP over TLS/SSL class - metacpan.org
書式の違いは次の通りです。
- 半年経過したファイルは年月日の日付だけ
-rw-r--r-- 1 1007 1007 11941 Jan 30 2019 yome.jpg - 半年以内のファイルは月日と日時の両方
-rw------- 1 1007 1007 155225 Sep 6 19:46 takoluka.jpg
#!/usr/bin/env perl
use v5.26;
use utf8;
use warnings;
use strict;
use feature "say";
use open IO => ":utf8";
use DateTime;
use DateTime::Format::Strptime;
use Encode::Argv;
use Encode::Locale;
binmode STDOUT, ":encoding(console_out)";
binmode STDERR, ":encoding(console_out)";
$| = 1;
my @test_data = (
{
case => "半年超過",
string => "-rw-r--r-- 1 1007 1007 11941 Jan 30 2019 yome.jpg",
},
{
case => "半年以内で去年",
string => "-rw------- 1 1007 1007 155225 Sep 6 19:46 takoluka.jpg",
},
{
case => "半年以内で今年",
string => "-rw------- 1 1007 1007 155225 Jan 15 13:14 luka.jpg",
},
);
for (@test_data) {
say "ケース:$_->{case}";
say "文字列:$_->{string}";
my $dt = file_datetime($_->{string});
say "日時:" . $dt->strftime("%F %T");
say "-----";
}
exit;
sub file_datetime {
my ($file_status) = @_;
my @field = split / +/, $file_status, 9;
my $dt_str = join " ", @field[5..7];
my $file_dt;
if ($dt_str =~ /:/) {
# 半年以内
my $strp = DateTime::Format::Strptime->new(pattern => "%b %d %R %Y");
# 現在日時
my $now_dt = DateTime->now(time_zone => "local");
# 今年前提でパース
$file_dt = $strp->parse_datetime($dt_str . " " . $now_dt->year);
# 現在日時より進んでしまった場合は去年でパース
$file_dt = $strp->parse_datetime("$dt_str @{[$now_dt->year - 1]}") if DateTime->compare($now_dt, $file_dt) < 0;
} else {
# 半年超過
$file_dt = DateTime::Format::Strptime->new(pattern => "%b %d %Y")->parse_datetime($dt_str);
}
return $file_dt;
}
ケース:半年超過 文字列:-rw-r--r-- 1 1007 1007 11941 Jan 30 2019 yome.jpg 日時:2019-01-30 00:00:00 ----- ケース:半年以内で去年 文字列:-rw------- 1 1007 1007 155225 Sep 6 19:46 takoluka.jpg 日時:2019-09-06 19:46:00 ----- ケース:半年以内で今年 文字列:-rw------- 1 1007 1007 155225 Jan 15 13:14 luka.jpg 日時:2020-01-15 13:14:00 -----
Net::FTPSSLには同一書式でファイル情報を返すインターフェースがあるのでそれを使えば、2種類の書式(3種類の条件)の切り分けを省けます。
mlsd( [DIRECTORY [, PATTERN [, FTYPE]]] ) Returns a list of files/directories in a standardized machine readable format designed for easy parsing. modify=20041027194930;type=file;size=28194; foo modify=20041027194932;type=file;size=3201931; pub modify=20180329120944;type=dir;size=256; bar