Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Looping through multiple directories

by dotowwxo (Acolyte)
on Dec 26, 2017 at 02:01 UTC ( [id://1206184]=perlquestion: print w/replies, xml ) Need Help??

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

Hi all, I am pretty new to Perl so please show mercy :')

Current code:

@ARGV = </cygdrive/c/Users/abc123/Documents/dude/logs/*.log>; while (<>){ #mycodes }

What I am trying to achieve is to loop through multiple directories full of logs files instead of just 1 directory. Any idea how I can achieve that?

Any response is greatly appreciated... Thank you all

Replies are listed 'Best First'.
Re: Looping through multiple directories
by karlgoethebier (Abbot) on Dec 26, 2017 at 13:27 UTC
    "...loop through multiple directories full of logs files..."

    Finding them might be an option:

    #!/usr/bin/env perl use strict; use warnings; use File::Find::Rule; use Data::Dump; use Try::Tiny; use feature qw(say); my @dirs = qw(./logs); my @files = File::Find::Rule->file()->name('*.log')->exec( \&acme )->i +n(@dirs); dd \@files; sub acme { say shift; try { ...; } catch { print $_; }; } __END__ karls-mac-mini:dotowwxo karl$ ./dotowwxo.pl dotowwxo1.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo10.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo2.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo3.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo4.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo5.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo6.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo7.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo8.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo9.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo1.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo10.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo2.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo3.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo4.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo5.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo6.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo7.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo8.log Unimplemented at ./dotowwxo.pl line 19. dotowwxo9.log Unimplemented at ./dotowwxo.pl line 19. [ "logs/bar/dotowwxo1.log", "logs/bar/dotowwxo10.log", "logs/bar/dotowwxo2.log", "logs/bar/dotowwxo3.log", "logs/bar/dotowwxo4.log", "logs/bar/dotowwxo5.log", "logs/bar/dotowwxo6.log", "logs/bar/dotowwxo7.log", "logs/bar/dotowwxo8.log", "logs/bar/dotowwxo9.log", "logs/foo/dotowwxo1.log", "logs/foo/dotowwxo10.log", "logs/foo/dotowwxo2.log", "logs/foo/dotowwxo3.log", "logs/foo/dotowwxo4.log", "logs/foo/dotowwxo5.log", "logs/foo/dotowwxo6.log", "logs/foo/dotowwxo7.log", "logs/foo/dotowwxo8.log", "logs/foo/dotowwxo9.log", ]

    Please note also that File::Find::Rule comes also with a built-in grep.

    Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Re: Looping through multiple directories
by NetWallah (Canon) on Dec 26, 2017 at 02:48 UTC
    Your first assignment to @ARGV is actually an I/O command (because it uses <>).

    You have specified the file-handle for that I/O as a "wildcard directory", which evaluates to a null file handle.

    Update: See Athanasius++ response below - I hade forgotten that <*> is a synonym for glob.

    The I/O results in @ARGV being empty, and hanging waiting on STDIN at the next <> operator.

    Try changing the first statement to :

    @ARGV = glob "/cygdrive/c/Users/abc123/Documents/dude/logs/*.log";
    And also, use strict and warnings!.

                    We're living in a golden age. All you need is gold. -- D.W. Robertson.

      Hello NetWallah,

      Your first assignment to @ARGV is actually an I/O command (because it uses <>).

      Sorry, no:

      13:35 >perl -MO=Deparse 1848_SoPW.pl use File::Glob (); @ARGV = glob('/cygdrive/c/Users/abc123/Documents/dude/logs/*.log'); while (defined($_ = readline ARGV)) { (); } 1848_SoPW.pl syntax OK 13:35 >

      To dotowwxo:

      From the documentation for glob:

      Note that glob splits its arguments on whitespace and treats each segment as separate pattern. As such, glob("*.c *.h") matches all files with a .c or .h extension.

      So, so specify multiple directories, you simply include each in the expression input to glob. But if you have a lot of directories, it may be more convenient to do something like this:

      my @dirs = qw( dir1 dir2 ); # add more as required @ARGV = (); push @ARGV, <./1848_SoPW/$_/*\.log> for @dirs;

      or, equivalently,

      my @dirs = qw( dir1 dir2 ); @ARGV = map { <./1848_SoPW/$_/*\.log> } @dirs;

      Update: The problem described by NetWallah above will occur if @ARGV should happen to be empty when the while (<>) { loop is entered. So it’s safer to handle this as a special case:

      use strict; use warnings; my @dirs = qw( dir1 dir2 ); @ARGV = map { <./1848_SoPW/$_/*\.log> } @dirs; if (@ARGV) { while (<>) { ... } }

      Hope that helps,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        Hi, thank you so much for your response. May I ask what  map { <./1848_SoPW/$_/*\.log> } @dirs; does?

        Hello, I've tried to your way.. Here's the result

        My code:
        use strict; use warnings; my $dirs1 = </cygdrive/c/Users/attwwwe1/Documents/dude/logs/*.logs>; my $dirs2 = </cygdrive/c/Users/attwwwe1/Documents/dude/logs2/*.logs>; my @dirs = qw($dirs1 $dirs2); @ARGV = map { <./1848_SoPW/$_/*\.log> } @dirs; if (@ARGV){ while(<>){ #somework } } else{ print "none"; }
        It just prints none every single time I run my script... Not sure what's wrong but it doesn't seem to work.
Re: Looping through multiple directories
by Anonymous Monk on Dec 26, 2017 at 13:37 UTC
      File::Find is a core module, so there's no need to even head to CPAN. Every JAPH should know them.

      #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: Looping through multiple directories
by thanos1983 (Parson) on Dec 26, 2017 at 17:22 UTC

    Hello dotowwxo,

    It looks like the fellow Monks have provided you with several different approaches/solutions to your problem.

    Just to add something minor here since you said that you are new to Perl, I think it would be good to read a similar question @ARGV and glob. it contains explanation and examples, hopefully you will learn a few "new" things.

    Hope this helps, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1206184]
Approved by Athanasius
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (3)
As of 2024-04-25 22:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found