Substituindo alguns caracteres em uma string por outro caractere

Eu tenho uma corda como

AxxBCyyyDEFzzLMN 

Eu quero replace todos os y e z com _ para que a saída seja

 A_BC_DEF_LMN 

Como fazer isso?

Eu conheço uma série de

 echo "$string" | tr 'x' '_' | tr 'y' '_' 

vai funcionar, mas eu quero fazer isso de uma só vez, sem usar canos.

EDIT: Os seguintes trabalhou

 echo "$string" | tr '[xyz]' '_' 

 echo "$string" | tr xyz _ 

replaceia cada ocorrência de x , y ou z por _ , fornecendo A__BC___DEF__LMN em seu exemplo.

 echo "$string" | sed -r 's/[xyz]+/_/g' 

replaceia ocorrências repetidas de x , y ou z com um único _ , fornecendo A_BC_DEF_LMN em seu exemplo.

Usando a Expansão do Parâmetro Bash :

 orig="AxxBCyyyDEFzzLMN" mod=${orig//[xyz]/_} 

Você pode achar este link útil:

http://tldp.org/LDP/abs/html/string-manipulation.html

Em geral,

Para replace a primeira correspondência de $ substring por $ replacement:

 ${string/substring/replacement} 

Para replace todas as correspondências de $ substring por $ replacement:

 ${string//substring/replacement} 

EDIT: Observe que isso se aplica a uma variável denominada $ string.

 read filename ; sed -i 's/letter/newletter/g' "$filename" #letter 

^ use o máximo que você precisar, e você pode fazer sua própria criptografia BASIC

Aqui está uma solução com a expansão de parâmetros do shell que substitui várias ocorrências contíguas por um único _ :

 $ var=AxxBCyyyDEFzzLMN $ echo "${var//+([xyz])/_}" A_BC_DEF_LMN 

Observe que o +( pattern ) requer correspondência estendida de padrões, ativada

 shopt -s extglob 

Alternativamente, com a opção -s (“squeeze”) de tr :

 $ tr -s xyz _ < << "$var" A_BC_DEF_LMN