Se você realmente quiser usar sed em vez de grep , você pode ter faz uma pesquisa & substitua e apenas imprima apenas se corresponder a algo:
sed -n 's%.*\(<?xml .*</canonMessage>\).*%%p' < input
Aqui estamos, por padrão, -n ot linhas de impressão, depois fazemos uma pesquisa e substituição do texto <?xml ...</canonMessage> ; o parêntese escapado em torno desse texto "captura" em espaços numerados. Ao adicionar greedy .* regex capturas antes e depois do texto XML desejado, podemos substituir a linha inteira pelo texto salvo em e depois imprimir a linha resultante.
Eu usei % para separar o texto da pesquisa e o texto substituto, porque o </canonMessage> tem o típico separador de barra. Se você gosta mais do separador de barra, basta escapar do que está tentando corresponder:
sed -n 's/.*\(<?xml .*<\/canonMessage>\).*//p' < input