use strict;
use warnings;
use POSIX qw(strftime); # 日付をフォーマットするために使用
use File::Basename qw(basename); # ファイルパスからファイル名部分のみを取得するために使用
# --- 設定 (ここを編集してください) ---
# 処理対象のフォルダを指定してください。
my $target_directory = "."; # ★★★ 対象フォルダを実際のパスに書き換えてください ★★★
# 対象とするファイルの拡張子を指定してください (ドットなし、例: "txt", "log")
my $file_extension = "txt"; # ★★★ 対象の拡張子を書き換えてください ★★★
# 何日以上前のファイルを古いと判断するかの日数を指定してください
my $days_threshold = 8; # ★★★ 日数を書き換えてください ★★★
# --- グローバル変数 ---
# 各グループの最新ファイル情報を格納するハッシュ
my %latest_files_in_group;
# --- メイン処理 ---
# 1. ファイル一覧の取得と解析
# 指定されたディレクトリの指定された拡張子のファイルを取得
my $glob_pattern = "$target_directory/*.$file_extension";
my @filepaths = glob $glob_pattern;
unless (@filepaths) {
print "対象となる *.$file_extension ファイルがディレクトリ '$target_directory' に見つかりませんでした。\n";
print "指定したパスや拡張子が正しいか、そのフォルダに該当ファイルが存在するか確認してください。\n";
exit;
}
# 正規表現内で使用するために拡張子をエスケープ
my $escaped_extension = quotemeta($file_extension);
foreach my $filepath (@filepaths) {
my $filename = basename($filepath); # パスからファイル名部分のみを抽出
# ファイル名からグループ名と数値を抽出
# 正規表現: グループ名部分(.*?) と 数値部分(\d+) を抽出。
# グループ名にはスペースが含まれる可能性があり、グループ名と数値の間の区切りは必ず半角スペース1つ。
if ($filename =~ /^(.*?) (\d+)\.$escaped_extension$/) { # <--- 正規表現を修正しました
my $group_name = $1;
my $number = int($2); # 数値として比較するため整数に変換
# ファイルの最終更新日時 (mtime) を取得 (エポック秒)
my $timestamp = (stat $filepath)[9];
unless (defined $timestamp) {
warn "警告: ファイル '$filepath' の日時情報を取得できませんでした。スキップします。\n";
next;
}
# グループごとに、数値が最も大きいファイルを記録
if ( (not exists $latest_files_in_group{$group_name}) or
($number > $latest_files_in_group{$group_name}{number}) ) {
$latest_files_in_group{$group_name} = {
name => $filename,
number => $number,
timestamp => $timestamp,
path => $filepath
};
}
}
}
# パターンにマッチするファイルが一つも見つからなかった場合の処理
unless (keys %latest_files_in_group) {
print "指定された命名パターン(グループ名<半角スペース1つ>数値.$file_extension)にマッチするファイルが\n";
print "ディレクトリ '$target_directory' に見つかりませんでした。\n";
exit;
}
# 2. 各グループで数値が一番高いファイルの一覧を表示
print "\n";
print "--------------------------------------------------\n";
print "各グループで数値が一番高いファイルの一覧 (対象: $target_directory/*.$file_extension):\n";
print "--------------------------------------------------\n";
printf "%-35s %-20s\n", "ファイル名", "最終更新日時"; # ヘッダー表示
print "-" x 55, "\n"; # 区切り線
my @sorted_group_names = sort keys %latest_files_in_group;
my @all_latest_file_details; # 後のフィルタリングで使用するため、詳細情報を一時保存
foreach my $group_name (@sorted_group_names) {
my $file_info = $latest_files_in_group{$group_name};
my $formatted_date = strftime "%Y-%m-%d", localtime($file_info->{timestamp});
printf "%-35s %-20s\n", $file_info->{name}, $formatted_date;
push @all_latest_file_details, $file_info; # 詳細情報を保存
}
print "--------------------------------------------------\n";
# 3. 指定された日数以上昔に更新されたファイルのみの一覧を表示
print "\n";
print "--------------------------------------------------\n";
print "上記一覧のうち、最終更新日が$days_threshold日以上前のファイルの一覧:\n";
print "--------------------------------------------------\n";
printf "%-35s %-20s\n", "ファイル名", "最終更新日時"; # ヘッダー表示
print "-" x 55, "\n"; # 区切り線
my $current_time = time(); # 現在のエポック秒
my $age_threshold_seconds = $days_threshold * 24 * 60 * 60; # 指定された日数の秒数
my $cutoff_timestamp = $current_time - $age_threshold_seconds; # カットオフとなるエポック秒
my $found_old_files_count = 0;
foreach my $file_info (@all_latest_file_details) {
if ($file_info->{timestamp} < $cutoff_timestamp) {
my $formatted_date = strftime "%Y-%m-%d", localtime($file_info->{timestamp});
printf "%-35s %-20s\n", $file_info->{name}, $formatted_date;
$found_old_files_count++;
}
}
if ($found_old_files_count == 0) {
print "最終更新日が$days_threshold日以上前のファイルはありませんでした。\n";
}
print "--------------------------------------------------\n";
print "\nスクリプトの実行が完了しました。\n";
$a=<>;