Isso deve funcionar. Eu sinto alguns problemas em somente afetar a primeira ocorrência de <parent>...</parent> e </modelVersion> *$ - senão poderia ser mais simples. Ele também escapa de todos os caracteres a ppended corretamente apenas no caso.
sed -e'/^ *<parent>/!d;:n' \
-e'$d;N;/\n *<.parent>/!bn' \
-e's/[\[:space:]]/\&/g' \
-e's|.*\(.\n\)|/<.modelVersion> *$/a&|;q' a.xml |
sed -e'1,/<\/modelVersion> *$/{' -f- -e\} b.xml
Não tenho 100% de certeza de que o BSD sed reconhecerá - para significar stdin. Se bem me lembro, faz , mas, apenas no caso, você pode substituir o -f- pelo switch e o argumento -f/dev/fd/0 se você precisar.
Aqui está o script que o primeiro sed grava no segundo stdin de sed :
/<.modelVersion> *$/a\
\ \ \ \ <parent>\
\ \ \ \ \ \ \ \ ...\
\ \ \ \ </parent>
E quando o segundo sed coincide com o primeiro </modelVersion> *$ na entrada, ele anexa a sequência para se parecer com:
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
...
</parent>
</project>