Eu testei seu script com o GNU sed e ele produziu o resultado esperado. No entanto, isso não é portável para outras versões de sed , já que você usa \n dentro de [] e na substituição, que é indefinida pelo padrão.
Usá-lo na substituição pode ser facilmente evitado:
sed -e '1h;2,$H;$!d;g' -e 's/\(macroa{\([a-z]*\) [^\n]*\)\(\nmacrob{\) //g'
Para usá-lo na expressão [] pode ser feito com um truque - você usa o comando y para trocar a nova linha com um caractere normal antes da substituição e alterá-lo novamente depois; neste caso eu uso | :
sed -e '1h;2,$H;$!d;g' -e 'y/\n|/|\n/;s/\(macroa{\([a-z]*\) [^|]*\)\(|macrob{\) //g;y/\n|/|\n/'
Esta é a solução universal, mas acho que é feia. Na maioria dos casos, em vez de [^\n] , você pode escrever [[:print:]] , porque normalmente todo o código, exceto as novas linhas, consiste em caracteres imprimíveis, portanto, é:
sed 'H;1h;$!d;g;s/\(macroa{\([a-z]*\) [[:print:]]*\)\n\(macrob{\) /\n/g'
(também simplifiquei seu 1h;2,$H inicial para H;1h .)
Considerando o comentário de don_crissti, acrescento que a abordagem típica para resolver esse tipo de problema é o ciclo N;P;D : sempre adicione a linha N ext, processe os dois juntos, P rint a primeira linha e D elete a partir do espaço padrão para continuar com o segundo:
sed 'N;s/\(macroa{\)\([a-z]* \)\(.*\nmacrob{\)//;P;D'