views:

161

answers:

3

The following Perl code has an obvious inefficiency;

while (<>)
{
if ($ARGV =~ /\d+\.\d+\.\d+/) {next;}
... or do something useful
}

The code will step through every line of the file we don't want.

On the size of files this particular script is running on this is unlikely to make a noticeable difference, but for the sake of learning; How can I junk the whole file <> is working and move to the next one?

The purpose of this is because the sever this script runs on stores old versions of apps with the version number in the file name, I'm only interested in the current version.

+12  A: 

grep ARGV first.

@ARGV = grep { $_ !~ /\d+\.\d+\.\d+/ } @ARGV;

while (<>)
{
  # do something with the other files
}
Paul Roub
IC, you just filter @ARGV like you would any other list.
Chris Huang-Leaver
+7  A: 

Paul Roub's answer works for more information, see The IO operators section of perlop man page. The pattern of using grep is mentioned as well as a few other things related to <>.

Take note of the mention of ARGV::readonly regarding things like:

perl dangerous.pl 'rm -rfv *|'
mikegrb
+1 for relevant links.
Chris Huang-Leaver
+12  A: 

Paul Roub's solution is best if you can filter @ARGV before you start reading any files.

If you have to skip a file after you've begun iterating it,

while (<>) {
    if (/# Skip the rest of this file/) {
        close ARGV;
        next;
    }
    print "$ARGV: $_";
}
ephemient
I would accept this answer too if I could.
Chris Huang-Leaver