Reputation: 59
Here is my code. I wish to extract part of the text and write into another file. The loop of the code do not stop at my selected range of text. It read until the final match line of word. Please advise me. Thanks. For example, I need to extract the $ NAME: sandy until $$.TO and then join with the contents inside $NAME: patrick which is start from G1 until $$SRU.
TEXT:
$ NAME : corry
$$.Inc s d
$$.Oc s
$$.TO
G1 ty n1 EE EE M T1 T2 $$SRU
G2 n1 y OO OO M T3 T4 $$SRU
$$.EON
$ NAME : patrick
$$.Inc c d
$$.Oc c
$$.TO
G1 td n3 EE EE M T5 T6 $$SRU
G2 n3 y OO OO M T7 T8 $$SRU
$$.EON
$ NAME : sandy
$$.Inc k l
$$.Oc l
$$.TO
G1 td n3 FF FF M R5 R6 $$SRU
G2 n3 y OO OO N R7 R8 $$SRU
$$.EON
OUTPUT:eg.
$ NAME : sandy #from sandy section
$$.Inc k l #sandy
$$.Oc l #sandy
$$.TO #sandy
G1.G1o.n ty n1 EE EE M T1 T2 $$SRU #from Patrick section
G2.G2o.n n1 y OO OO M T3 T4 $$SRU #Patrick
Fe.id.n ty n1 EE EE N T1 T2 $$SRU #corry
Fr.in.p n1 y OO OO N T3 T4 $$SRU #corry
$$.EON #Patrick
CODE:
use strict;
use warnings;
open my $F1, '<', 'testing.txt' or die "failed $!";
open my $F2, '>', 'out.txt' or die "failed $!";
while (<$F1>) {
if (/^\$ NAME : sandy/../\$.TO/) {
print $F2 $_;
}
if (/^\$ NAME : patrick/../\$.EON/) {
if(/^G1/../\$SRU/){
s/G1/G1.G1o.n/g;
print $F2 $_;}
}
}
close $F1;
close $F2;
Upvotes: 2
Views: 174
Reputation: 2501
You can parse all the file to one big hash, and do everything you want with its elements: combine, change etc
use strict;
use warnings;
use Data::Dumper;
open my $F1, '<', 'in' or die "failed $!";
open my $F2, '>', 'out.txt' or die "failed $!";
my %elements;
my $current_element;
while (<$F1>) {
if ( /^\$ NAME : (\w+)/ .. /\$\$[.]EON/ ) {
if ( /^\$ NAME : (\w+)/ ) {
$current_element = $1;
}
if ( /^G1/ ) {
$elements{$current_element}->{g1} .= $_;
}
elsif ( /^G2/ ) {
$elements{$current_element}->{g2} .= $_;
}
elsif ( ! /\$\$[.]EON/ ) {
$elements{$current_element}->{text} .= $_;
}
}
}
close $F1;
$elements{patrick}->{g1} =~ s/G1/G1.G1o.n/;
$elements{patrick}->{g2} =~ s/G1/G2.G2o.n/;
$elements{corry}->{g1} =~ s/G1/Fe.id.n/;
$elements{corry}->{g2} =~ s/G2/Fr.in.p/;
print $F2 "$elements{sandy}->{text}$elements{patrick}->{g1}$elements{patrick}->{g2}$elements{corry}->{g1}$elements{corry}->{g2}\n\$\$.EON";
close $F2;
this will parse all the file to hash that looks like:
so if you want to combine text
from sandy and G1
from patric you can do
my $sandy_patric = $elements{sandy}->{text}.$elements{patrick}->{g1};
Upvotes: 2
Reputation: 36262
You were not far from a solution. I would set a flag when inside the patrick
section I find the line that begins with G1
, and I would save each line in an array (after substitution) to append it after processing the sandy
section:
#!/usr/bin/env perl
use warnings;
use strict;
my (@patrick, $flag);
open my $F1, '<', 'testing.txt' or die "failed $!";
open my $F2, '>', 'out.txt' or die "failed $!";
while ( <$F1> ) {
if (/^\$ NAME : sandy/../\$\.TO/) {
print $F2 $_;
}
if (/^\$ NAME : patrick/../\$\.EON/) {
if ( m/\AG1/ ) { $flag = 1 }
if ( $flag ) {
s/\A(G\d+)/$1.$1o.n/;
#print $F2 $_;
push @patrick, $_;
}
}
}
print $F2 $_ for @patrick;
close $F1;
close $F2;
It will create a file out.txt
with content:
$ NAME : sandy
$$.Inc k l
$$.Oc l
$$.TO
G1.G1o.n td n3 EE EE M T5 T6 $$SRU
G2.G2o.n n3 y OO OO M T7 T8 $$SRU
$$.EON
Upvotes: 0