in reply to Printing all the files that have both ".rtf" and ".ftp" by searching recursively in a given directory

Seems like my earlier query was not clear,explain better here.

For example ,I have files foo.rtf and foo.ftp in a given directory.I want to print such files(print either of them).Basically any two different files with same name but different extension namely .rtf and .ftp needs to be printed.I tried the following but its not printing anything?Can anyone advise?

use warnings; use strict; use File::Find::Rule; use Data::Dumper; my @files = File::Find::Rule->file() ->name( qr/\.(rtf&ftp)$/ ) ->in( './' ); print Dumper(\@files);
  • Comment on Printing files that has two different extensions in a given directory
  • Download Code

Replies are listed 'Best First'.
Re: Printing files that has two different extensions in a given directory
by Corion (Patriarch) on Apr 12, 2011 at 20:36 UTC

    What is the following code supposed to do?

    qr/\.(rtf&ftp)$/

    Where in perlre is that way of working documented?

    Personally, I wouldn't try to cram the whole logic into File::Find::Rule. I would partition the work as follows:

    1. Find all files
    2. Remove all file names that don't end in .rtf or .ftp
    3. Sort the filenames
    4. For each .ftp file, look if the file following it has an identical name, except for the last four letters.
Re: Printing files that has two different extensions in a given directory
by ikegami (Patriarch) on Apr 12, 2011 at 20:43 UTC

    You're still very unclear, but I'm pretty sure you want the following:

    For each file matching *.rtf, print its name if that directory also has similarly named file with the .ftp extension.

    my @dirs = File::Find::Rule ->directory() ->in('.'); for my $dir (@dirs) { my @rtfs = File::Find::Rule ->maxdepth(1) ->file() ->in($dir); for my $rtf (@rtfs) { ( my $ftp = $rtf ) =~ s/\.rtf\z/.ftp/; if (-e $ftp) { print("$rtf\n"); } } }

    Update: Condensed:

    my @files = File::Find::Rule ->file() ->name('*.rtf') ->exec(sub{ my $rtf = $_; ( my $ftp = $rtf ) =~ s/\.rtf\z/.ftp/; -e $ftp; }) ->in('.');

      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

        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.

Re: Printing files that has two different extensions in a given directory
by ikegami (Patriarch) on Apr 12, 2011 at 20:35 UTC

    So: if a file has the .rtf extension or if it has the .ftp extension, prints its name.

    my @files = File::Find::Rule ->file() ->name( qr/\.(?:rtf|ftp)\z/ ) ->in( '.' );