.*
tenta corresponder o maior número possível de caracteres, e é por isso que você recebe o restante da linha. Então, em vez de .
(qualquer caractere), você precisa usar [^;]
(qualquer caractere, exceto o ponto-e-vírgula):
grep -o ';101=[^;]*\|;103=[^;]*'
Não tenho certeza do que tentei alcançar com -m 1
em um único liner. De qualquer forma, você precisa combinar sua saída em uma linha para obter o resultado desejado. Mas aposto que você pode descobrir como fazer isso sozinho (no final, é o seu exercício, não o nosso).