Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 列出相同的文件并按顺序对文件名进行排序_Perl - Fatal编程技术网

Perl 列出相同的文件并按顺序对文件名进行排序

Perl 列出相同的文件并按顺序对文件名进行排序,perl,Perl,我正在编写一个程序,列出参数中给出的相同文件,并在打印时按字母顺序排列文件名 如果参数是file1,file2,file3,file4,file5,如果file2和file3相同,如果file4和file5相同,则输出应为: file1 file2, file3 file4, file5 我试图做的是使用foreach循环遍历每个参数,并测试文件是否存在,然后比较文件内容,并使用cmp对文件名进行排序 #!/usr/bin/perl -w use File::Basename; use Fi

我正在编写一个程序,列出参数中给出的相同文件,并在打印时按字母顺序排列文件名

如果参数是
file1
file2
file3
file4
file5
,如果
file2
file3
相同,如果
file4
file5
相同,则输出应为:

file1
file2, file3
file4, file5
我试图做的是使用foreach循环遍历每个参数,并测试文件是否存在,然后比较文件内容,并使用cmp对文件名进行排序

#!/usr/bin/perl -w

use File::Basename;
use File::Compare;

die "Usage $0: <files>\n" if @ARGV != 1;

foreach $args(@ARGV){
    if (-e $args){
       #not sure how to do 
    }
}
#/usr/bin/perl-w
使用File::Basename;
使用File::Compare;
如果@ARGV!=1.
foreach$args(@ARGV){
如果(-e$args){
#不知道怎么办
}
}

以上是我刚刚写的内容,我不确定如何比较几个文件的内容,如果我想打印出一个文件的名称,我是否只需执行$I=basename$file然后打印$I?

很可能有一个更优雅的解决方案,但这应该可以满足您的需要:

#!/usr/bin/perl

use strict;
use warnings;

use File::Compare qw( compare );

@ARGV = sort grep -e $_, @ARGV;

my %printed;
for my $i1 (0..$#ARGV-1) {
    my $file1 = $ARGV[$i1];
    next if $printed{$file1};

    my @set = $file1;

    for my $i2 ($i+1..$#ARGV) {
        my $file2 = $ARGV[$i2];

        if (compare($file1, $file2) == 0) {
            push @set, $file2;
            $printed{$file2} = 1;
        }
    }

    print "@set\n";
}

此方法为每个文件计算SHA1摘要,并使用该摘要确定相同的文件,而不必重复比较整个文件:

#!/usr/bin/env perl
use warnings;
use strict;
use feature qw/say/;
use Digest::SHA;

die "Usage: $0 FILES\n" if @ARGV == 1;

my %filegroups;
for my $file (grep { -e $_ } @ARGV) {
    push @{ $filegroups{ Digest::SHA->new(1)->addfile($file)->digest } }, $file;
}

local $, = ", ";
for my $group ( sort keys %filegroups ) {
    say sort @{ $filegroups{$group} };
}
在一些示例文件上运行:

$ perl filesort.pl file[1-5]                                                                
file2, file3
file1
file4, file5
显示文件时,每组相同的文件以任意但一致的方式排序(通过对其摘要进行排序),然后在每组中按名称排序

如果您只需要一个简单的已排序文件名列表,a可以:


您只需要比较相邻的文件名吗?或者,文件1和文件5可能是相同的,而其他文件都不同吗?文件有多大?@ysh这些信息没有在作业中给出,所以我真的不知道。如果您有任何问题,请告诉我。这是非常低效的。这是非常低效的。无论另一个文件大小是否相同,您都在读取每个文件。(此外,您可能需要仔细检查以确保具有相同哈希的两个文件实际上是相同的。)@ikegami如果您不喜欢其他人的答案,请随意发布您自己的答案。这不会正确排序文件名。(我发布了一个补丁,但肖恩恢复了)
my @files =
  map  { $_->[0] }
  sort { $a->[1] cmp $b->[1] || $a->[0] cmp $b->[0] }
  map  { [ $_, Digest::SHA->new(1)->addfile($_)->digest ] } @ARGV;