use strict; undef $/; my %seen; my @para = split /(\n\n+)/, <>; while (defined($_ = shift @para)) { die "No From line!\n" unless /^From /; my ($id) = map /^Message-ID:\s(\S.*)/im, split /\n(?! )/; warn "No Message-ID! [[$_]]\n" unless defined $id; $_ .= shift @para while @para and $para[0] !~ /^From /; print unless defined $id and $seen{$id}++; }