如何将3小时前的文件移至归档文件夹且不覆盖已有文件?
解决Perl脚本移动文件时覆盖同名文件的问题
首先,咱们先明确两个核心问题需要修正:一是原脚本里修改时间的判断逻辑(-M返回的是天数,3小时得转换成天数),二是避免覆盖目标目录里的同名文件。
修正后的完整脚本
#!/usr/bin/perl use strict; use warnings; use File::Find; use File::Copy qw(move); use File::Basename qw(basename); my $dstdir = '/data/ARCHIVE/'; # 确保归档目录存在,不存在则创建 mkdir $dstdir unless -d $dstdir; @ARGV = ("/tmp/test1") unless @ARGV; print STDERR "Begin @ ", scalar localtime, "\n"; find( sub { # 只处理普通文件,且修改时间超过3小时(3/24=0.125天) if (-f $_ && -M $_ > 3/24) { my $src_file = $File::Find::name; my $base_name = basename($src_file); my $dst_file = "$dstdir/$base_name"; # 生成唯一的目标文件名,避免覆盖 my $counter = 1; while (-e $dst_file) { # 如果文件存在,添加递增后缀,比如file.txt -> file_1.txt my ($name, $ext) = $base_name =~ /^(.*)(\.[^.]+)?$/; $ext = '' unless defined $ext; $dst_file = "$dstdir/${name}_${counter}${ext}"; $counter++; } # 执行移动操作 if (move($src_file, $dst_file)) { print STDERR "Moved: $src_file -> $dst_file\n"; } else { print STDERR "Failed to move $src_file: $!\n"; } } }, @ARGV ); print STDERR "End @ ", scalar localtime, "\n";
关键改动说明
- 修改时间判断:
-M $_返回的是文件最后修改时间距离当前时间的天数,所以3小时需要转换成3/24(即0.125天),这样才能正确筛选出修改超过3小时的文件。 - 确保归档目录存在:添加
mkdir $dstdir unless -d $dstdir,避免因为目标目录不存在导致移动失败。 - 唯一文件名生成:
- 先获取源文件的基础文件名,比如
test.txt。 - 检查目标目录中是否已存在该文件,如果存在,就拆分文件名和扩展名,添加递增的数字后缀(比如
test_1.txt、test_2.txt),直到找到一个不存在的文件名。 - 这个逻辑兼容带扩展名和不带扩展名的文件(比如
readme会变成readme_1)。
- 先获取源文件的基础文件名,比如
- 错误提示:移动操作后增加了成功/失败的日志输出,方便排查问题。
额外注意事项
- 如果你的源目录和归档目录在不同的文件系统上,
File::Copy的move函数会先复制再删除源文件,这是正常行为。 - 脚本开头的
use strict和use warnings一定要保留,能帮你提前发现语法或逻辑错误。
内容的提问来源于stack exchange,提问作者user260834
相关产品推荐
相关产品推荐

