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

Hello Everyone, I'm traversing a directory structure and I want to open every txt file and log file to find some data. I want to ignore all other files.

I'm having trouble with the following code snippet:

next unless ($path =~ /[\.txt|\.log]/);
I initally tried:
next if !($path =~ /[\.txt|\.log]/);
This would seem so simple! :(

edited: Wed May 14 20:47:13 2003 by jeffa - code tags

Replies are listed 'Best First'.
Re: next if regex matches
by VSarkiss (Monsignor) on May 14, 2003 at 20:25 UTC

    The square brackets are unnecessary. next unless $path =~ /\.(log|txt)$/;You could also be a little more parsimonious: next unless $path =~ /\.(?:log|txt)$/;Thus avoiding a (presumably unnecessary) capture to $1.

    The square brackets are also what made your post render weird. ;-)

      This worked exactly as needed! Thanks
      another form of negation could be
      next if $path !~ /\.(?:log|txt)$/;
        Sorry monks.

        To late i noticed that Enlil already mentioned my comment. So i'll go up to my room and flagelate myself.

Re: next if regex matches
by Zaxo (Archbishop) on May 14, 2003 at 20:31 UTC

    You need code tags, but the linking of '\.log' suggests that you have square brackets around that in the regex. Try: next unless ($path =~ /\.log$/); Square brackets will turn that into a character class, testing for any of the individual characters of '.log'.

    Have you looked at File::Find or glob for this task?

    After Compline,
    Zaxo

      Zaxo,
      Exactly what I was thinking - unless there is something the OP isn't telling us, there is no need to even do the work.
      #!/usr/bin/perl -w use strict; while (glob("*.txt *.log")) { print "$_\n"; }
      Where you only get .txt and .log files, although I would have used <*.txt *.log>.

      Cheers - L~R

Re: next if regex matches
by broquaint (Abbot) on May 14, 2003 at 21:49 UTC
    As others have already provided you with an answer, I'll provide you with an alternate solution :)
    use File::Find::Rule; my @files = find( file => name => [ '*.txt', '*.log' ], in => $your_path_here );
    That should find all *.{txt,log} files in the directories in and below $your_path_here and store them as filenames in @files. Ain't File::Find::Rule great folks?
    HTH

    _________
    broquaint

Re: next if regex matches
by Enlil (Parson) on May 14, 2003 at 20:31 UTC
    I think you are using character classes for alternation and hence getting the wrong result (ie [\.txt|\.log] this is the same as [.txt|log] in that it would match if any of the characters inside the character class that exist at that position, which in this case is anywhere in the string.)

    Both of these should work:

    next unless ($path =~ /\.(?:txt|log)$/); next if ( $path !~ /\.(?:txt|log)$/;
    update: I added the $ to your original regex to match the end of the line (or before newline at the end), as I am assuming that these are the extensions to the files and hence will only appear at the very end of the string (you don't want a file like foo.txt.tmp matching)

    -enlil

Re: next if regex matches
by cmapuk (Novice) on May 15, 2003 at 23:36 UTC
    @txtfiles=</path/to/dir/*.txt>;


    Save me, St.Perldoc!