Here is a quick hack that does the job,
on a data set that I constructed based on my understanding of your problem statement.
#!/usr/bin/perl
use strict;
use warnings;
my $verbose = 0;
my @lines = <DATA>;
my @items = split /(env\n\s*\{|\{|\})/, join '', @lines;
for (@items) {
print "###$_###" if $verbose;
}
my $depth = 0;
my $inenv = 0;
my @envblocks;
my @envblock;
for (@items) {
print ">>>$inenv.$depth---$_\n" if $verbose;
++$inenv if ($depth == 0 && /env\n\s*\{/);
++$depth if (/\{/);
if ($inenv){
push @envblock, $_;
if ($depth == 1 && /\}/) {
push @envblocks, join '', @envblock;
@envblock = ();
--$inenv;
}
}
--$depth if (/\}/);
print "<<<$inenv.$depth---$_\n" if $verbose;
}
for (@envblocks) {
print "===\n$_\n===\n";
}
__DATA__
somestuff
morestuff
env
{
111
env
{
333
}
}
and more stuff
and things
zut
{
222
env
{
444
}
}
env
{
777
env
{
555
}
}
finally a few more things
and the output - does it look like what you expect?
===
env
{
111
env
{
333
}
}
===
===
env
{
777
env
{
555
}
}
===
I won't try to explain it. perlfunc and perlre do a better job of that.
HTH.
Rudif