Aqui está uma solução pura:
for i in *:*; do
mv "$i" "${i//:/_}"
done
O formato ${var//pattern/replacement}
substituirá todas as ocorrências de pattern
por replacement
na variável $var
. Para obter mais informações sobre os recursos de manipulação de string do bash, consulte aqui .
Se você quiser fazer isso para vários caracteres, pode simplesmente colocá-los em uma classe de caracteres. Por exemplo, para substituir todos os ;
, :
, =
, +
, %
, ,
com sublinhados, você poderia fazer:
$ ls
1foo:bar 2foo:bar:baz 3foo;bar 4foo=bar 5foo%bar 6foo,bar 7foo+bar
$ for i in *; do mv "$i" "${i//[:;=%,+]/_}"; done
$ ls
1foo_bar 2foo_bar_baz 3foo_bar 4foo_bar 5foo_bar 6foo_bar 7foo_bar
Basicamente, a ideia é que [ ]
significa any of the characters listed
. Então, colocando todos os caracteres que você deseja substituir na classe de personagem, todos eles são tratados de uma só vez.
Para os caracteres específicos que você pediu, as coisas são um pouco mais complexas porque alguns deles precisam ser escapou (estou ignorando o /
, já que * nix não permite nomes de arquivos mais do que o Windows faz isso não será um problema):
$ ls
1foo<bar 2foo>bar 3foo:bar 4foo\bar 5foo|bar 6foo*bar 7foo?bar 8foo"bar 9foo'bar
$ for i in *; do mv "$i" "${i//[<>:\|*\'\"?]/_}"; done
$ ls
1foo_bar 2foo_bar 3foo_bar 4foo_bar 5foo_bar 6foo_bar 7foo_bar 8foo_bar 9foo_bar
Observe que escapei de \
, '
e "
adicionando um \
na frente de cada um.