CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
Extracting from an array

 



xlantis
New User

Feb 9, 2011, 9:09 AM

Post #1 of 7 (1667 views)
Extracting from an array Can't Post

Hi all, im trying to purse a file. First reading it's entire contents into an array and then only printing the contant between to defined markers #start & #end .. here's the code:


Code
open DATA,'<',"file.txt"; 
@array = <DATA>;
close(DATA);

print map { /#start/ .. /^#end/ }, @array;


I know this is incorrect but I hope it demonstrates what i am trying to do.

thanks for any help.. I'd like to be able to do this in just 1 line of code Crazy


BillKSmith
Veteran

Feb 9, 2011, 1:52 PM

Post #2 of 7 (1661 views)
Re: [xlantis] Extracting from an array [In reply to] Can't Post

Use grep instead of map.
Good Luck,
Bill


rpaskudniak
User


Feb 16, 2011, 5:17 PM

Post #3 of 7 (1605 views)
Re: [xlantis] Extracting from an array [In reply to] Can't Post

Bill,

I think grep would print only the lines containing #start and #end, ignoring all else.

When I have had to selectively look at lines, I used a state variable

Code
my $state = 0; 
my $ix = 0; # Array index
my $line_buf;
my @array;

open DATA,'<',"file.txt";
while ($line_buf = <DATA>)
{
if ($line_buf =~ /#start/) {$state = 1; next}
elsif ($line_buf =~ /#end/) {$state = 0; next}
if ($state == 1) {$array[$lc++] = $line_buf;}
}

print @array;


Yes, this could be shortened a few ways, like eliminating the array and using:

Code
if ($state == 1) {print $line_buf, "\n";}

but I was pushing for clarity.

This help?

By the way, the patterns should probably be /^#start/ and /^#end/

Note that I have not assumed there is only one pair of #start and #end markers.
--------------------
-- Rasputin Paskudniak (In perpetual pursuit of undomesticated, semi-aquatic avians)


BillKSmith
Veteran

Feb 16, 2011, 8:17 PM

Post #4 of 7 (1604 views)
Re: [rpaskudniak] Extracting from an array [In reply to] Can't Post


Quote
think grep would print only the lines containing #start and #end, ignoring all else.



Refer to "range operator" in perldoc perlop


Code
use strict; 
use warnings;
my @array = (
'aaaaaaaaaaaa',
'#start',
'dfkjf',
'dkfkj',
'dljdj',
'#end',
'bbbbbbbbbbbbb',
);

$, = "\n";
print grep {/#start/ ... /#end/} @array

Good Luck,
Bill


rpaskudniak
User


Feb 16, 2011, 9:45 PM

Post #5 of 7 (1598 views)
Re: [BillKSmith] Extracting from an array [In reply to] Can't Post

Bill, I tried your code verbatim, except that I added the last ; to the print line.

I stand corrected - the grep command, used with the range operator, did not print only the marker lines but all lines in between. However, the marker lines also printed.

Code
Maxwell:/home/RP/test:6$ ./billk.pl 
#start
dfkjf
dkfkj
dljdj
#endMaxwell:/home/RP/test:7$

OK, so we needed to add a "\n" to print command. But you see the markers. That was probably not xlantis's intent. Another objection, which may also not have been his (her?) intent, was that my method accounts for multiple start/end pairs. So I amended your code a bit to add a second pair (as well as that missing "\n")to prove my objection.

Code
#!/usr/bin/perl 
use strict;
use warnings;
my @array = (
'aaaaaaaaaaaa',
'#start',
'dfkjf',
'dkfkj',
'dljdj',
'#end',
'bbbbbbbbbbbbb', ,
'cccccccccccccc',
'#start',
'zzzzzzzzzzzzz',
'yyyyy',
'xxxxxxxxxxxx',
'#end',
'past the second end',
'Another line past send end'
);

$, = "\n";
print grep {/#start/ ... /#end/} @array;
print "\n";

And here's the output:

Quote
#start
dfkjf
dkfkj
dljdj
#end
#start
zzzzzzzzzzzzz
yyyyy
xxxxxxxxxxxx
#end

So my objection is overruled; this skipped the lines between the first #end and the second #start. A remarkable property of grep; thanks for the lesson.

I am hereby reduced back to one objection - the display of the delimiter lines.
--------------------
-- Rasputin Paskudniak (In perpetual pursuit of undomesticated, semi-aquatic avians)


BillKSmith
Veteran

Feb 17, 2011, 6:35 AM

Post #6 of 7 (1588 views)
Re: [rpaskudniak] Extracting from an array [In reply to] Can't Post


Quote
I am hereby reduced back to one objection - the display of the delimiter lines.



Remove them explicitly if you do not want them.


Code
print grep {/#start/ ... /#end/ and !/start/ and !/#end/} @array;

Good Luck,
Bill


leathan
Novice

Feb 24, 2011, 7:59 PM

Post #7 of 7 (1543 views)
Re: [BillKSmith] Extracting from an array [In reply to] Can't Post

I prefer more human readable code, and hence hate grep, but i recognize its power and recommend it!

<3 being a hypocrite


Edit: Not using grep helps you see more whats going on in your brain, its the same very basic type of logic used even in writing compilers and it should be understood not just implemented optimally


(This post was edited by leathan on Feb 24, 2011, 8:01 PM)

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives