perl_mystery has asked for the wisdom of the Perl Monks concerning the following question:

Hi , I have an array @plf_files which contains a list of .plf names,now I have a file "@file" which contains .plfs as shown below,now for every .plf found in @file,I want to open each .plf ,search recursively until no .plf is found in it and save them in an array,how do I make sure the process of opening and searching recursively happens?
#!/usr/bin/perl -w use strict; use warnings; my (@recursive_plfs,plf_files) =(); @plf_files = {files.plf,orphans.plf,bases.plf}; @file = {//source/perl/scripts/modem/final/rel/sw/bases.plf#30,//sourc +e/perl/scripts/modem/final/rel/sw/files.plf#3}; foreach my $plf (@plf_files) { if (grep @file) { push @recursive_plfs=$plf; #the below loop needs to be repeated until no .plf's are found,how do +I do this? { open my $match, '<',"$plf" or die "could not open '$plf' $!"; push @recursive_plfs = /\/(\w+\.plf)/ = grep (/\*\.plf$/,$match) #get +only the plf name from the match } } }

Replies are listed 'Best First'.
Re: Recursive search
by Anonymous Monk on Dec 17, 2010 at 00:31 UTC
    the below loop needs to be repeated until no .plf's are found,how do I do this?

    First explain in words how to do it

      grep (/\*\.plf$/,$match) shouldn't return anything which tells there are no further .plf's found...

        grep (/\*\.plf$/,$match) shouldn't return anything which tells there are no further .plf's found...

        So you're finished?

      why isn't my below code printing anything?It should search recursively in the .plf's and print them,not sure where is it going wrong?

      #!/usr/bin/perl -w use strict; use warnings; my @recursive_plfs =(); my ($plf,$match_plf, $match_plf_name); my @plf_files = {"files.plf","orphans.plf"}; print @plf_files; my @file = "PLF=//source/perl/scripts/build/software/files.plf#30"; foreach my $plf (@plf_files) { print $plf; if (grep (/\Q$plf\E/i,@file)) { push @recursive_plfs,$plf; recrusion($plf); } } sub recursion { open my $DATA, '<',"$plf" or die "could not open '$plf' $!"; foreach (my $line = <$DATA>){ if(grep (/\.plf$/,$line)) { $match_plf = grep (/\.plf$/,$line); print $match_plf; $match_plf_name =~ /\/(\w+\.plf)/;#get only the plf name(files.plf) f +rom //source/perl/scripts/build/software/files.plf#30 push @recursive_plfs ,$match_plf_name; recursion($match_plf_name); } } } print @recursive_plfs;

        Your code contains lots of syntax errors. For example the name of your subroutine is spelled in two different ways. This is wrong.

        In Perl, checking whether a single value matches a regular expression is best done by using the =~ operator, see perlop. Instead of

        grep(/.../, $item)

        use

        $item =~ /.../

        Also, it helps very much to understand code if it is indented properly. So, for each block, indent that block by (say) four spaces, until that block ends. This shows the structure that underlies your code. For example the first foreach loop will look like this if properly indented:

        foreach my $plf (@plf_files) { print $plf; if (grep (/\Q$plf\E/i,@file)) { push @recursive_plfs,$plf; recrusion($plf); } }

        This makes it far easier to spot what code belongs to which branch.

        my @plf_files = {"files.plf","orphans.plf"};creates a single element array containing a reference to a hash, because you used { } (called a 'composer'). You probably meant:
        my @plf_files = ('files.plf','orphans.plf');

        Your subroutine tests the same thing several times, try this:
        sub recursion { my $plf = shift; open my $fh, '<', $plf or die "could not open '$plf' $!"; foreach (my $line = <$fh>){ if($line =~ /(\w+\.plf)$/) { $match_plf_name = $1; next if $match_plf_name eq $plf; push @recursive_plfs ,$match_plf_name; recursion($match_plf_name); } } }
        You will notice that I don't use $DATA for filehandle name. This is because there is a reserved filehandle called DATA, so $DATA would be confusing. You will also notice that there is not a grep in sight. The capturing parentheses group is saved into $1.

        Finally, notice also the 'next' statement as an insurance against infinite recursion.