Gostaria de renomear uma série de arquivos com o nome
name (10).ext
name (11).ext
...
para
name_10.ext
name_11.ext
...
Este one-liner funciona:
$ for i in name\ \(* ; do echo "$i" | sed -e 's! (\([0-9]\{2\}\))!_!' ; done
name_10.ext
name_11.ext
...
Mas este não:
$ for i in name\ \(* ; do mv "$i" "$(echo "$i" | sed -e 's! (\([0-9]\{2\}\))!_!')" ; done
bash: !_!': event not found
Por quê? Como evitar isso?
Usando
$ bash --version
GNU bash, versione 4.3.48(1)-release (x86_64-pc-linux-gnu)
no Ubuntu 18.04.
Enquanto nesta pergunta semelhante , um caso simples com ! é mostrado, aqui um ! apenas dentro de aspas simples é considerado e comparado a um ! entre aspas simples, entre aspas duplas. Como apontado nos comentários, Bash se comporta de maneira diferente nesses dois casos. Trata-se da versão do Bash 4.3.48(1) ; este problema parece não estar mais presente em 4.4.12(1) (no entanto, é recomendado evitar este one-liner, porque a versão do Bash pode ser desconhecida em alguns casos).
Como sugerido na resposta de Kusalananda, se o sed delimitador ! for substituído por # ,
$ for i in name\ \(* ; do mv "$i" "$(echo "$i" | sed -e 's# (\([0-9]\{2\}\))#_#')" ; done
este problema não surge de todo.