use strict; use warnings; my @stack; while() { if( s|^(<(\d+)>.*)(\n)|$1\n| ) { print pop @stack while @stack and substr( $stack[-1], 2, -2 ) >= $2; push @stack, $3; } print; } print reverse @stack; __DATA__ <1>one data data data data <2>two data data data data <3>three data data data data <3>blah data data data data <2>blah data data data data <4>zoom data data data data <4>zoom data data data data <1>data data data data data