Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

A question about perl grep 2

Status
Not open for further replies.

lcs01

Programmer
Joined
Aug 2, 2006
Messages
182
Location
US
In unix, we can do somthing like this:

Code:
% grep string1 *.txt | grep -v string2

Can perl grep does the same? If so, what is the correct syntax? I tried to search in this forum and google on the web, but no luck.

Thank you for your help.
 
Here you go
Code:
#!/usr/bin/perl

my $x = qx { string1 *.txt | grep -v string2 };
chomp $x;
print $x;

M. Brooks
 
hmmm.... that hardly perl code. [hammer] [smile]

- Kevin, perl coder unexceptional!
 
Code:
use File::Slurp qw(read_file);

my @lines = grep {/string1/ && ! /string2/} map {read_file($_)} glob('*.txt');

This code will accomplish what you want but it will be missing the filename headers that grep on unix so nice adds. Also, it will load all your text files into memory at once, instead of performing this operation sequentially. Both of these issues could be fixed by adding more lines to this code, but this will simply demonstrate that, yes, the same can be accomplished in perl pretty easily.
 
>> And yes, it's Perl.

Yes it's perl, but it's just using perl to run the same system commands and capture the output. But maybe that is what the OP wanted to know how to do.

- Kevin, perl coder unexceptional!
 
I prefer to only pull the finger of a well known aquaintance, and only if I know what they ate for dinner last night.

[cheers]

- Kevin, perl coder unexceptional!
 
if (Friday) { drink }
else { drink less }

[flush]



- Kevin, perl coder unexceptional!
 
To Miller, that's exactly what I am looking for! Thank you!

Also thank Kevin & mbrooks for your help and comments.
 
After I saw Miller's code, I did a bit more experiment and I found that we do not need use File::Slurp qw(read_file)!

A simple solution would be:

Code:
my @lines = grep (/string1/ && ! /string2/, @buffer);
# @buffer is the contents of a source file to be parsed

How simple is that!!
 
A follow-up question:

Compare the following two implementations:

1st:
Code:
my $srce = "./sourcefile.txt";
open(FH, $srce);
my @buf = <FH>;
close(FH);
my @lines = grep (/string1/ && ! /string2/, @buffer);

and 2nd:
Code:
my $srce = "./sourcefile.txt";
my @lines = grep {/string1/ && ! /string2/} map {read_file($_)} glob($srce);

Which one is more efficient and why?

Thanks!
 
lcs01 said:
A follow-up question:

Compare the following two implementations:

...

Which one is more efficient and why?

Neither is more efficient. Mine simply has less writing involved and is easier to read (personal opinion). Actually, the original reason I used read_file was because I was assuming that you needed to read more than one file. That is why I used the glob function as well. Without that requirement, the code could be simplified to.

Code:
use File::Slurp qw(read_file);
my @lines = grep {/string1/ && ! /string2/} read_file("./sourcefile.txt");

But reading in the file contents using open accomplishes the exact same thing.
 
Compare the following two implementations:

Without testing I would guess the first implementaton is a little bit more efficient. The code is straight forward and there is no anonymous data structures to deal with. I would be surprised though if it were much more efficient. Only testing with the real data would tell though. Use the benchmark module to test the two blocks of code if you really need to know which is more efficient.

- Kevin, perl coder unexceptional!
 
Kevin, would the first implementation use more memory? The actual source file is huge ~50 mbytes.
 
KevinADC said:
Without testing I would guess the first implementaton is a little bit more efficient.
[/CODE]

Come on Kevin. Use a little imagination :)

The difference between IO operations, and IO operations hidden behind a function call are infinitesimal. The only additional time involved is that which takes to install the module using cpan.
 
lcs01 said:
The actual source file is huge ~50 mbytes.

lcs01: If the file is that large, then you absolutely should not be slurping. Do line by line processing instead.

Code:
my $srce = "./sourcefile.txt";
open(FH, $srce);
my @lines = ();
while (<FH>) {
    push @lines, $_ if /string1/ && ! /string2/;
}
close(FH);
 
Thank you, Miller!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top