2
sub open_directory {
    my $directory = shift @_;
    my @files = ();

    opendir (my $dh, $directory) or die "Couldn't open dir '$directory' : $!";
    my @all_files = readdir $dh;
    closedir $dh;

    foreach my $files(@all_files){
            while($files =~ /\.htm/){
                push(@files);
            }
    }
    return @files;
}

The error is at the code push(@files); The error is : Useless use of push with no values

I want to process the files with the the name ending of .htm or .html in the @files array using the regex /\.htm/ please help me.

3
  • 2
    There error message means that you forgot to specify what to push into the array. Think about it. Commented May 3, 2013 at 8:26
  • 1
    Also, the while should really be an if. Commented May 3, 2013 at 8:28
  • i guess something like this should work? push(@files, $files); Commented May 3, 2013 at 8:31

3 Answers 3

5

The most simply way to solve this is by using the grep builtin: It selects those elements from a list where a condition is true, then returns the list of all matching elements E.g.

my @even = grep { $_ % 2 == 0 } 1 .. 10; # even number in the interval [1, 10].

In our case, we can do

my @files = grep { /\.htm/ } readdir $dh;

If you want to use push, then you (a) have to specify what you want to push onto the array, and (b) should only do the pushing if the regex matches, not while it matches:

for my $file (@all_files) {
  push @files, $file if $file =~ /\.htm/;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much. I have solved this small problem :) if($files =~ /\.htm/){ push(@files,$files); }
@DeepakTivari Be aware that that regex will also consider (for example) foobar.htm.tar.gz a valid file name. (Because the regex is not anchored to the end of the file name)
oh yes thank you for pointing that out. I am still doing beginner stuff but will remember to set the regex properly :D
2

amon has given the correct answer to your question, using grep to filter the file names. However, the functionality you are trying to accomplish sounds more like a glob to me:

my @html_files = glob("*.html *htm");  # html files

You can also insert a directory:

my $dir = "foo";
my @html_files = glob("$dir/*.html $dir/*.htm");

Comments

0

Try to understand the below code, this will process only .htm or .html files.

use strict;
use Data::Dumper;

my @all_files = ("abc.htm", "xyz.gif", "pqr.html") ;
my @files;
foreach my $files(@all_files){
    if($files =~ /\.html?/){ # This will process only .htm or .html files
        push(@files, $files);
    }
}
print Dumper(\@files);

output:

$VAR1 = [
          'abc.htm',
          'pqr.html'
        ];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.