in reply to Re^2: 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

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.

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

Replies are listed 'Best First'.
Re^4: Printing files that has two different extensions in a given directory
by JavaFan (Canon) on Apr 12, 2011 at 21:20 UTC
    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.

        Wait, you have a file system that allows two different files with the same name in a given directory?
Re^4: Printing files that has two different extensions in a given directory
by Anonymous Monk on Apr 12, 2011 at 21:45 UTC

    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.