use Data::Peek; my %d; while () { s/^\s*>?\s*(.*?)[\s\r\n]*\z/$1/; m/^(\d+)$/ ? push @{$d{$a}} => $1 : ($a = $_); } DDumper \%d; __END__ >James >40 >James >35 >James >26 >James >15 James 10 >12 >Philip 10 4 >5 Philip James Philip 18