1

My problem is that I am not able to figure out that why my code is taking each of the line from the file as one element of an array instead of taking the whole record starting from AD to SS as one element of the array. As you can see that my file is starting from AD and ending at SS which is same for all the followed lines in the data. But I want to make the array having elements starting from AD to SS which will be having all the lines in between AD to SS that is BC....,EG...., FA.....etc.not each line as an element. I tried my way and get the same file as such.Could anyone check my code. Thanks in advance.

AD uuu23

BC jjj

EG iii

FA vvv

SS

AD hhh25

BC kkk

EG ppp

FA aaa

SS

AD ttt26

BC xxx

FA rrr

SS

#!/usr/bin/env perl
 use strict;
 use warnings;

 my $ifh;
 my $line = '';
 my @data;

 my $ifn  = "fac.txt";

 open ($ifh, "<$ifn") || die "can't open $ifn";
 my $a = "AD  "; 
 my $b = "SS ";
 my $_ = " ";
 while ($line = <$ifh>)
 {
 chomp 
 if ($line =~ m/$a/g); {
  $line = $_;

  push @data, $line;

 while ($line = <$ifh>) 
{
$line .= $_;

push @data, $line;

last if 
($line =~ m/$b/g);
}

}
push @data, $line; }


print @data;
2
  • chomp if (line =~ m/$a/g); Looks like a typo there. What's with declaring a new $_ variable? And new $a and $b variables? This code is rather messy. Commented Aug 3, 2011 at 8:49
  • Your code is a mess. Start by indenting it correctly so that it is readable. Commented Aug 3, 2011 at 9:34

3 Answers 3

2

If I understand correctly your problem, the fact is that the way you are reading the file:

while ($line = <$ifh>)

is inherently a line-by-line approach. It uses the content of the "line termination variable" ($/) to understand where to split lines. One easy way to change this behavior is un-defining the $/:

 my $oldTerminator = $/;
 undef $/;
 ....... <your processing here>
 $/ = $oldTerminator;

so, your file would be just one line, but I am not sure what would happen of your code.

Another approach is the following (keeping in mind what I said about the fact that you are reading the file line-by-line): instead of doing

`push @data, $line;`

at each iteration of your loop, just accumulate the lines you read in a variable

$line .= $_;

(like you already do), and do the push only at the end, just once. Actually, this second approach will be more easily applicable to your code (you only have to remove the two push statements you have and put one outside of the loop).

Sign up to request clarification or add additional context in comments.

Comments

1

I believe part of your problem is here

chomp 
 if ($line =~ m/$a/g);

it should be

chomp;
if ($line =~ m/$a/g)

otherwise the if statement is always executed. Please update your question if this has helped you advance

Comments

0

Here's a way to accomplish reading the records into an array, with newlines removed:

Code:

use strict;
use warnings;
use autodie;

my @data;
my $record;
my $file = "fac.txt";
open my $fh, '<', $file;

while (<$fh>) {
    chomp;
    if (/^AD /) { # new record starts
        $record = $_;
        while (<$fh>) {
            chomp;
            $record .= $_;
            last if /^SS\s*/;
        }
        push @data, $record;
    } else { die "Data outside record: $_" }
}

use Data::Dumper;
print Dumper \@data;

Output:

$VAR1 = [
          'AD uuu23BC jjjEG iiiFA vvvSS',
          'AD hhh25BC kkkEG pppFA aaaSS',
          'AD ttt26BC xxxFA rrrSS'
        ];

This is another version, using the input record separator $/:

use strict;
use warnings;
use autodie;

my $file = "fac.txt";
open my $fh, '<', $file;

my @data;
$/ = "\nSS";
while (<$fh>) {
    s/\n//g;
    push @data, $_;
}

use Data::Dumper;
print Dumper \@data;

Produces the same output with this data. It does not care about the record start characters, only the end, which is SS at the beginning of a line.

3 Comments

Thank you TLP for clearing the concept. I will try and let you know if there would be any problem. Thanks a lot.
could you explain me about the function of Data Dumper. I tried but it is not getting much clear. I will be thankful to you.
Data::Dumper just formats the data for you. A nice way to print a variable. It doesn't do anything else. The data in the array is as you see it, three strings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.