4

所以我为自己设计了一个小项目来帮助学习 Perl,这是我可以实际使用的东西。这个想法是比较 2 个目录中的文件修改日期列表。1 从 FTP 和 1 在我的本地,如果它们较新,则从本地上传(这部分可以稍后处理)。我创建了单独的脚本(我计划将它们组合起来,目前只是在修补),一个用于从 FTP 读取目录并获取文件。另一个比较2个目录中的文件列表(文件列表位于一个数组中),这就是问题所在。我可以得到它来比较两个目录。我似乎无法锻炼如何让它比较同名文件。如果只有一个目录中存在文件,它将将该文件与同一数组位置中的另一个文件进行比较。

这可以很容易地用 if 语句处理(我说很容易,但我不确定),但无法理解哪些参数会这样做。

到目前为止我所拥有的:

 opendir(IMD, "/TRAINING/Perl") || die("Cannot open directory"); 
        @thefiles= readdir(IMD); 
        opendir(IMD2, "/TRAINING/Perl2") || die("Cannot open directory"); 
        @thefiles2= readdir(IMD2)

    foreach my $file (@thefiles) {
     #  if ($file != @thefiles2[$counter]){
        if (compare($file, @thefiles2[$counter]) == 0){
            print $file, " Matches ";
            print @thefiles2[$counter], "\n";   
            $counter++;
        }

     #  elsif ($file == @thefiles2[$counter]){  
        elsif (compare($file, @thefiles2[$counter]) != 0){
            print $file, " ";
            print "Does not match";
            print @thefiles2[$counter], "\n";
            $counter++; 
        }
    }

目前我只是比较相同数组位置的文件名,直到我可以正常工作,然后将其更改为使用日期。已经使用 -M 了,但现在正在做同样的事情。我意识到这远非我所需要的,并且确实需要任何指针,尤其是因为我的编程总体上很笨拙。

基本上我想要它做的,

If ($file1 !exists in $dir2){
    Print "not exists"
}
If ($file1 exists in $dir2){
    Compare its date with $file2 in $dir2 and print newer/older
}

如果我现在可以让它工作,那么我可以慢慢地将它修改为我想要它做的事情。

感谢你们可以为我提供的任何帮助。

4

2 回答 2

2

首先是你必须使用相对路径,而不是绝对路径。否则你永远不会得到匹配。因此,如果“基本”文件夹是 /Folder,那么文件 /Folder/subfolder/file 应该表示为 subfolder/file。

下一步是加载两个哈希,一个带有来自第一个位置的文件,另一个带有来自第二个位置的文件。使用相对路径作为键,然后值可以是您可以用来衡量“平等”的其他信息。修改时间,或文件大小,或 MD5 ......随你的便。

然后,您逐步检查第一个散列中的所有键,检查第二个散列中的每个键。如果它不存在,则该文件不在第二个位置(新文件?)。如果确实存在,那么您可以检查“平等”的相关值以查看文件是否已更新/更改。当您找到匹配项时,从第二个哈希中删除该键。然后,第二个哈希中剩下的是第一个位置不存在的文件(已删除的文件?)。

不过,这是棘手的事情。如果您尝试镜像,则必须了解文件夹。如果要添加文件,则必须先按排序顺序执行文件夹...例如,以便在尝试创建子文件夹/子文件夹 2/ 之前 mkdir 子文件夹/。

相反,如果您要删除内容,则必须颠倒上述操作...首先删除文件,然后按降序删除文件夹...例如,在尝试 rmdir subfolder/ 之前删除 subfolder/subfolder2/。

最后,您还必须能够影响接收端文件的修改时间。当您将文件 FTP 到服务器时,它将获取当前时间。这意味着如果您使用 MTIME 作为判断文件是否为新文件的一种方式,它将永远不会再次比较相等。并非所有 FTP 服务器都有更新文件时间的方法。

祝你好运。最后,像 rsync 这样的东西是一个更好的解决方案。

于 2012-12-03T02:18:59.940 回答
1

首先,您不能依赖readdir返回有序列表的假设。因此,仅使用索引进行比较是错误的,即使您排序也不能依赖,因为可能存在其他目录中不存在的文件。此外,您的代码不适用于子目录。您可以使用的选项:

  • 使用 Perl 模块,例如File::DirWalk。这允许使用子目录,您可以制作包含文件路径及其修改时间的哈希,由stat返回
  • 使用 unix 实用程序,例如 BSD mtree(8)
于 2012-11-30T06:58:19.267 回答