Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: Question on File Handler and Subroutines in Perl

by thanos1983 (Parson)
on Mar 05, 2019 at 09:43 UTC ( [id://1230889]=note: print w/replies, xml ) Need Help??


in reply to Question on File Handler and Subroutines in Perl

Hello Anonymous Monk,

Perl is a well known scripting language that people choose to create 'Modules' that can assist you / us to reduce our lines of code to minimum. For example reading and loading all lines of a file in an array while removing the new line characters all in one line :)

One of the modules that I usually prefer to use is IO::All.

Then your task is simplified you just need to set the pattern to match (string or even multiple strings) and grep all elements that match your pattern using grep as you have done already :).

Small sample of code bellow:

#!/usr/bin/perl use strict; use warnings; use IO::All; use Data::Dumper; foreach my $file (@ARGV) { if ( -e $file ) { # double check existence my @lines = io($file)->chomp->slurp; # Chomp as you slurp if (my @matches = grep( /string/, @lines ) ) { print "Found in File: '$file':\n"; print Dumper \@matches; } } } __END__ $ perl test.pl a.txt b.txt c.txt Found in File: 'a.txt': $VAR1 = [ 'Line two interested, string' ]; Found in File: 'b.txt': $VAR1 = [ 'Line one interested, string', 'Line two interested, string' ]; __DATA__ $ cat a.txt b.txt c.txt Line one not interested Line two interested, string Line one interested, string Line two interested, string Line one not interested Line two not interested Line three not interested

You need to adjust it to your preferences but it should be close to what you want to achieve.

Update: I do not want to include the solution with the subroutine. There are several ways to put all your data together. One possible way I would suggest push. Give it a try and we will help you more if you get problems. After all programming / scripting is all about trying and failing until you get it right :)

Hope this helps, BR.

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

Replies are listed 'Best First'.
Re^2: Question on File Handler and Subroutines in Perl
by Anonymous Monk on Mar 05, 2019 at 09:57 UTC

    Hi thanos1983,

    Thank you for your detailed reply! (:

    I will take a look at your suggested solution. :) One thing I am still a bit puzzled about, is how to open a file that contains the names of the files in the current directory, and then iterate through them to print out lines that matches the pattern I want. I am currently still working on that.

    Thank you once again!

      Hello again Anonymous Monk,

      You are welcome :)

      Update: Sorry I got your last question completely wrong :). You can repeat the same procedure as you open the files and instead of @ARGV use @files.

      Sample of code:

      #!/usr/bin/perl use strict; use warnings; use IO::All; use Data::Dumper; my @files = io('fileName.txt')->chomp->slurp; print Dumper \@files; __END__ $ perl test.pl $VAR1 = [ 'a.txt', 'b.txt', 'c.txt' ];

      Update2: I think I finally understood what you mean. You want to provide a file as a parameter to the script that contains the names of the files that you want to search through for the keyword. If this is the case see bellow:

      #!/usr/bin/perl use strict; use warnings; use IO::All; use Data::Dumper; sub grepFileFromSubroutine { my @files = io(shift)->chomp->slurp; my @final; foreach my $file (@files) { if ( -e $file ) { # double check existence my @lines = io($file)->chomp->slurp; # Chomp as you slurp if (my @matches = grep( /string/, @lines ) ) { push @final, "Found in File: '$file':", @matches; } } } return \@final; } print Dumper grepFileFromSubroutine(@ARGV); __END__ $ perl test.pl fileName.txt $VAR1 = [ 'Found in File: \'a.txt\':', 'Line two interested, string', 'Found in File: \'b.txt\':', 'Line one interested, string', 'Line two interested, string' ]; __DATA__ $ cat a.txt b.txt c.txt Line one not interested Line two interested, string Line one interested, string Line two interested, string Line one not interested Line two not interested Line three not interested

      If still is not what you want provide us more information to assist you more :)

      Regarding your last question read this past question which contains also examples and a variety of solutions (Find filename that has the pattern in a directory).

      I usually prefer to use File::Find::Rule. A previously asked question with a sample of code with this module see (Re: Capturing and then opening multiple files).

      Hope this helps, BR.

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

        Hi thanos1983,

        Thank you very much for your detailed reply, and for coming back to my question despite having given a detailed reply previously.

        I am sorry for not wording my question properly too.

        No worries, I think reading the codes given by all of you gave me more ideas on how to write a Perl program in future. :D I have not learnt about the modules and how to deal with the scoping operator as I am only at Chapter 2 of "Learn Perl the Hard Way". I will get there and return to this thread to look at all of your (including the other PerlMonks') answers. (:

        Thank you once again! :D

        I realized you cancelled the sentences in the last 2 paragraphs too. May I ask if those are references for me when I get to the, let's say, more advanced stages of Perl?

        Thank you (:

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1230889]
help
Chatterbox?
and the web crawler heard nothing...

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

    No recent polls found