Using GNU sed with the extended regex mode turned ON -E
- Store all non semicolon records in hold and wait for the semicolon record when the action begins.
- When we encounter the semicolon line, the merging process starts wherein the last portion of the pattern space(= semicolon line) is appended to the first portion of the pattern space and the first portion printed and stripped off. This continues till we exhaust the pattern space.
$ sed -Ee '/\n/ba
/^[^;]+$/,/;/!b
H;/;/!d;z;x;D;:a
s/\n(.*\n)?[^;]+(;.*)/\2&/
P;/\n.*\n/D;s/.*\n//
' file
$ perl -lne '$, = ";";
push(@A,$_),next if !/;/;
my $a = s/.*?;//r;
print $_, $a for splice @A;
print;
' file