Reputation: 505
I am trying to split a very large file into smaller files based string within the file.
eg. Input file
Block(A){
Block_area : 2.6112;
Block_footprint : 3BAA5927A22E66B0AE1214A806440F12;
}
Block(B){
Block_area : 2.6112;
Block_footprint : 3BAA5927A22E66B0AE1214A806440F12;
}
Block(C){
Block_area : 2.6112;
Block_footprint : 3BAA5927A22E66B0AE1214A806440F12;
}
I want to create three files each containing the data within the brakets
Could you please let me know where I am getting it wrong. my perl code
while (<PR>) {
if ($_ =~ ' Block\('))
{
chomp;
close (PW);
$textcell = $_;
$textcell =~ s/Block\(//g;
$textcell =~ s/\)\{//g;
open (PW, ">$textcell.txt") or die "check file";
}
if ( /^ Block\($textcell\)/../^ }/)
{ print PW $_;}
}
The desired files are being created but are empty.
regards
Desired output, three files:
A.txt
Block(A){
Block_area : 2.6112;
Block_footprint : 3BAA5927A22E66B0AE1214A806440F12;
}
B.txt
Block(B){
Block_area : 2.6112;
Block_footprint : 3BAA5927A22E66B0AE1214A806440F12;
}
C.txt
Block(C){
Block_area : 2.6112;
Block_footprint : 3BAA5927A22E66B0AE1214A806440F12;
}
Upvotes: 0
Views: 186
Reputation: 50637
I would suggest changing approach and read file in blocks instead of lines,
use strict;
use warnings;
use 5.010;
use autodie;
# input record separator is now '}' followed by old value of separator (i.e \n)
local $/ = "}$/";
while (<>) {
my ($file) = m|\( (.+?) \)|x or next;
open my $fh, ">", "$file.txt";
print $fh $_;
close $fh;
}
Upvotes: 1
Reputation: 126722
The problem is that your tests exclude anything that isn't a Block()
line. You do nothing at all for any other forms of the line. In addition, your second if
statement is checking that there are two spaces before Block
, which never occurs.
This is how I would write it. It assumes at least version 10 of Perl 5 so that I can use autodie
instead of checking the success of each open
call explicitly. Note that I have used the /x
modifier on my regular expression, so spaces and tabs are insignificant and I can use them to make the regex more readable.
use strict;
use warnings;
use 5.010;
use autodie;
open my $in_fh, '<', 'blocks.txt';
my $out_fh;
while (<$in_fh>) {
open $out_fh, '>', "$1.txt" if / Block \( (\w+) \) /x;
print $out_fh $_ if $out_fh;
}
Upvotes: 1