Esto se puede hacer simplemente con la sustitución de parámetros de shell:
# setup
line='hello&xyz!60!world'
string='&xyz!'
variable2='!'
# now, remove from the beginning up to the first instance of "&xyz!"
tmp=${line#*$string}
# $tmp now holds 60!world
# remove from the end the last "!" and all following characters
result=${tmp%$variable2*}
echo $result
# => 60
Parece que su comando sed está fallando debido a la coma
sin coma en la entrada, por lo que nada coincide, por lo tanto, nada impreso
$ set -x
$ echo "$line" | sed -nr "s/$string([0-9]+),$variable2/\1/ p"
+ sed -nr 's/&xyz!([0-9]+),!/\1/ p'
+ echo 'hello&xyz!60!world'
elimine la coma, ahora tenemos una coincidencia, pero el prefijo y el sufijo permanecen
$ echo "$line" | sed -nr "s/$string([0-9]+)$variable2/\1/ p"
+ sed -nr 's/&xyz!([0-9]+)!/\1/ p'
+ echo 'hello&xyz!60!world'
hello60world
también coincide con el texto anterior y posterior
$ echo "$line" | sed -nr "s/.*$string([0-9]+)$variable2.*/\1/ p"
+ sed -nr 's/.*&xyz!([0-9]+)!.*/\1/ p'
+ echo 'hello&xyz!60!world'
60