.* 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).