Com sed você pode fazer:
sed -e :1 -e 's/_\([^+]*@\)/?/;t1'
Substitua _ seguido por uma sequência de caracteres que não sejam + seguidos por @ com ? com a sequência do caractere e repita o processo, desde que corresponda.
Ou apenas entre EMAIL+ e SHR :
sed -e :1 -e 's/\(EMAIL+.*\)_\(.*SHR\)/?/;t1'
Se você quiser considerar apenas as linhas que começam com ^EFT , adicione um -e '/^EFT/!b' para deixar as que não gostam:
sed -e '/^EFT/!b' -e :1 -e 's/\(EMAIL+.*\)_\(.*SHR\)/?/;t1'
Observe que, para uma entrada como:
EFT EMAIL+ foo_bar SHR bar_baz EMAIL+ SHR
Ambos os sublinhados serão substituídos porque estão entre um EMAIL+ e um SHR .
Para evitar isso, você pode fazer algo como:
sed '
/^EFT/!b # leave the non-EFT lines alone (branch out)
s/%/%p/g; s/</%l/g; s/>/%r/g; # escape the <>% characters with %
s/EMAIL+/</g; s/SHR/>/g; # replace EMAIL+ and SHR with < and >
:1
s/\(<[^<>]*\)_\([^<>]*>\)/?/; t1
s/</EMAIL+/g; s/>/SHR/g; # restore EMAIL+ and SHR
s/%r/>/g; s/%l/</g; s/%p/%/g; # restore the escaped <>%'