use strict; use warnings; use Test::More tests => 1; my $want = <id1|id2|id3|Q51487|P-474-4|86-98,113-126,297-310,322-335 CSLIPDYQRPEAPVAAAYPQGQAYGQNTGAAAVPAADIGWREFFRDPQLQQLIGVALE EOT my %res; while () { if (/^>(.*?)\|(.*)/s) { my $id = $1; my $rest = $2; if (exists $res{$rest}) { $res{$rest}{keys} .= "|$id"; } else { my $seq = ; $res{$rest} = { keys => ">$id", seq => $seq, } } } } my ($k) = keys %res; # You would loop over all keys is your real prog my $have = "$res{$k}{keys}|$k$res{$k}{seq}"; is $have, $want; __DATA__ >id1|Q51487|P-474-4|86-98,113-126,297-310,322-335 CSLIPDYQRPEAPVAAAYPQGQAYGQNTGAAAVPAADIGWREFFRDPQLQQLIGVALE >id2|Q51487|P-474-4|86-98,113-126,297-310,322-335 CSLIPDYQRPEAPVAAAYPQGQAYGQNTGAAAVPAADIGWREFFRDPQLQQLIGVALE >id3|Q51487|P-474-4|86-98,113-126,297-310,322-335 CSLIPDYQRPEAPVAAAYPQGQAYGQNTGAAAVPAADIGWREFFRDPQLQQLIGVALE