Reputation: 1
I'm a Perl beginner (this is my second script beyond the practise manual), and I seem to be having a bit of trouble getting an if
statement to work.
The script is meant to read a document, take one line, parse it for a useful table (a section that starts with a text sequence and ends with >
) and then print it to the screen.
It seems to be getting stuck after printing the first text sequence (around line 20) after printing $line
. I added the "Just checking" in order to ascertain where the problem was occurring. Is it just something simple I am missing, or is there a flaw in my fundamental program logic?
use strict;
use warnings;
print "What file would you like to open? \n";
my $file = <STDIN>;
chop($file);
open( FILE, $file ) || die("Can not open $file");
while (<FILE>) {
my $bool = 0;
my $line = $_;
chop $line;
if ( !( $line =~ /text input/ ) && ( $bool == 0 ) ) {
next;
} elsif ( ( $line =~ /text input/ ) && ( $bool == 0 ) ) {
$bool = 1;
print $line;
next;
}
if ( ( $line =~ /^\s$/ ) && ( $bool == 1 ) ) {
print "just checking";
next;
}
if ( !( $line =~ /^>/ ) && ( $bool == 1 ) ) {
my @table = split( /\s{2,}/, my $table );
foreach (@table) {
print "$_ \n";
}
if ( ( $line =~ /^>/ ) && ( $bool == 1 ) ) {
print "last function ok";
last;
}
}
}
close($file);
exit;
Upvotes: 0
Views: 332
Reputation: 35198
It looks like you want to process lines between two patterns.
You can do that using a state variable $bool
, but you will need to declare that state variable outside the file processing loop. Currently it's being reinitialized to 0
before every line.
However, as a shortcut, you can use the Flip-Flop Operator ..
to look for lines between two patterns.
The following is a cleanup of your script:
use strict;
use warnings;
use autodie;
print "What file would you like to open? \n";
chomp( my $file = <STDIN> );
open my $fh, '<', $file;
while (<$fh>) {
if ( /text input/ ... /^>/ ) {
print;
}
}
Note:
...
because I wanted deferred testing of the end condition. This is in case the text input
line contains a >
at the start.As always, read the docs in detail before using a new operator or feature.
Upvotes: 2
Reputation: 91430
You also have a problem with these lines
if (!($line =~ /^>/) && ($bool == 1))
{
my @table = split(/\s{2,}/, my $table);
foreach(@table){
print "$_ \n";
}
if (($line =~ /^>/) && ($bool == 1))
{
print "last function ok";
last;
}
}
The last curly brace is misplaced, you never go to the line print "last function ok";
if ($line !~ /^>/ && $bool) {
my @table = split(/\s{2,}/, $line);
foreach (@table) {
print "$_ \n";
}
} # <=== here
if ($line =~ /^>/ && $bool) {
print "last function ok\n";
last;
}
Upvotes: 0
Reputation: 9520
There are a few points that might be causing problems in your script:
my @table = split(/\s{2,}/, my $table);
Here, you're splitting a newly-initialised variable, so you're never going to get any output. You probably want to split $line
, not $table
.
while (<FILE>)
{
my $bool = 0;
...
elsif (($line =~ /text input/) && ($bool == 0))
{
$bool = 1;
next;
}
You're setting $bool
to 0 at the start of each loop, and this line, which changes the value of $bool
, skips the rest of the loop, so none of the conditions where $bool == 1
are going to be tested. my $bool = 0
should go outside the while loop.
if (!($line =~ /^>/) ...
if (!($line =~/text input/ ...
You can use $line !~ /^>/
to check that the line does not start with >
and $line !~ /text input/
.
chop $line;
If you want to take off the line ending, chomp
will remove unix, win, and mac line endings.
You can take advantage of shorthand to assess the value of $bool
, and just type
if ($bool)
Perl evaluates 0
as false and 1
as true, so you'll save at least 5 characters of typing every time you use that to assess whether $bool
is 1. if (! $bool)
will save three characters of typing, but it looks so much cooler, don't you think?
If that hasn't solved the problem, you will have to post your input as it's difficult to know when you want to print the table.
Upvotes: 3
Reputation: 98398
Here:
while (<FILE>)
{
my $bool = 0;
my $line = $_;
chop $line;
if (!($line =~/text input/) && ($bool == 0))
$bool
will always be 0 at this point. I'm guessing maybe you meant to declare and initialize it outside the while loop, so it would persist over multiple lines?
Upvotes: 2