#!/usr/bin/perl use strict; use warnings; my $verbose = 0; my @lines = ; 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