in reply to Re: Printing files that has two different extensions in a given directory
in thread Printing all the files that have both ".rtf" and ".ftp" by searching recursively in a given directory

Thanks for the reply ikegami.I would like to make one correction,the corresponding .ftp file not necessarily should be in the same directory,it can be in any other directory.

For example,if the directory structure is like below c:\tests\foo.rtf c:\tests\data\foo.ftp if we run the script from c:\tests,it should print foo.rtf

  • Comment on Re^2: Printing files that has two different extensions in a given directory
  • Download Code

Replies are listed 'Best First'.
Re^3: Printing files that has two different extensions in a given directory
by ikegami (Patriarch) on Apr 12, 2011 at 21:08 UTC
    use strict; use warnings; use File::Find::Rule qw( ); use File::Basename qw( basename ); my %files; for ( File::Find::Rule ->file() ->name('*.rtf', '*.ftp') ->in('.') ) { my ($name, $ext) = basename($_) =~ /^(.*)\.(.*)\z/; ++$files{$name}{$ext}; } for my $name (%files) { print("$name\n") if $files{$name}{rtf} && $files{$name}{ftp}; }

    Update: Tested. Fixed.

      Without repeating the extension:
      use strict; use warnings; use File::Find::Rule qw( ); my %files; for ( File::Find::Rule ->file() ->name('*.rtf', '*.ftp') ->in('.') ) { my ($name) = /^(.*)\./; ++$files_by_ext{$name}; } say for grep {$files{$_} == 2} keys %files;

        I purposefully did not introduce the following errors from which your version suffers:

        • False positive when there are two .rtf and no .ftp with the same name.
        • False positive when there are no .rtf and two .ftp with the same name.
        • False negative when there are more than one .rtf and one .ftp with the same name.
        • False negative when there are one .rtf and more than one .ftp with the same name.
        • False negative when there are more than one .rtf and more than one .ftp with the same name.

        Don't know if it matters to the OP or not.

      Thanks,this is exactly what i want,but the thing is I want to print the absolute path ,instead of just the file names.Can you please advise? </p?

        hum. Earlier, you said "I only want to print the names of files" (Upd: ... but I see you meant you meant something quite different. )

        use strict; use warnings; use File::Find::Rule qw( ); use File::Basename qw( basename ); my %files; for ( File::Find::Rule ->file() ->name('*.rtf', '*.ftp') ->in('.') ) { my ($name, $ext) = basename($_) =~ /^(.*)\.(.*)\z/; push @{ $files{$name}{$ext} }, $_; } for my $name (%files) { if ($files{$name}{rtf} && $files{$name}{ftp}) { print "$_\n" for @{ $files{$name}{rtf} }, @{ $files{$name}{ftp} +}; } }

        This can probably be done cleaner.