
Eu entendo apenas um pouco sobre isso. O comando abaixo remove os espaços de todos os nomes de arquivos.
find . -type f -name "* *.*" -exec bash -c 'mv "$0" "${0// /}"' {} \;
Gostaria que também removesse vírgulas, pontos e parênteses (
, ,
, .
, (
e )
), mas não sei onde no comando colocar os caracteres que desejo remover.
Responder1
A resposta curta é: o comando para remover espaços, vírgulas, pontos e parênteses de um nome de arquivo (in $0
) é
mv "$0" "${0//[ ,.()]/}"
Mas não use isso…
Resposta mais longa:
Seu
find
comando diz-name "* *.*"
. Isso seleciona arquivos cujos nomes incluem pelo menos um espaço seguido de pelo menos um período. Faz sentido não tentar processar arquivos cujos nomes não contenham espaço(s), pois, se não houver espaços, não há nada a remover. Mas não sei por que esse comando está sendo testado por um período. Ele será renomeadofat cat.txt
parafatcat.txt
, mas permaneceráhot dog
intactofrank.fur ter
.Como você deseja renomear arquivos com pontos em seus nomes (para remover os pontos), você deve alterar seu
-name
teste para-name "*[ ,.()]*"
.Ao lidar com nomes de arquivos que não são conhecidos antecipadamente, é melhor colocá-los
--
antes do primeiro nome de arquivo. Pode-se argumentar que isso não é estritamente necessário quando você está fazendofind . … -exec …
, mas é um bom hábito adquirir.Se você tiver arquivos chamados
fat cat.txt
ef a t c a t.txt
, ambos serão renomeados parafatcat.txt
, e o segundo irá superar o primeiro. Passar a-n
opção (no-clobber) paramv
evitará que isso aconteça. Mas cuidado: isso deixará arquivos com espaços (etc.) em seus nomes e poderá nem mesmo informar que houve um problema!Seu comando atual invoca um novo
bash
processo para cada arquivo. Isso pode fazer com que demore mais do que o necessário. É preferível invocarbash
uma vez e depois invocarmv
várias vezes. Então, incorporando tudo o que foi dito acima, temosfind . -type f -name "*[ ,.()]*" -exec bash -c 'mv -n -- "$1" "${1//[ ,.()/}"' sh {} +
Mas espere! Ainda não terminamos! Não use o acima.
Quando
find
executa um comando (com-exec
), ele passa um nome de caminho do arquivo para o comando. Se você tiver um arquivo chamadofat cat.txt
em seu diretório atual,find
passará./fat cat.txt
para o comando bash. O comando acima tentará renomearfat cat.txt
(./fat cat.txt
) para/fatcattxt
. Se você estiver executando como root (ou seja,sudo
), isso moverá seus arquivos para o diretório raiz, causando uma grande bagunça. (Lição: não execute comandossudo
a menos que tenha certeza de que precisa deles.) Se você não estiver executando como root, a “boa notícia” é que o comando não fará nada.Então, agora, juntando tudo, obtemos
find . -type f -name "*[ ,.()]*" -exec bash -c 'for f do dir="$(dirname "$f")"; base="$(basename "$f")"; echo mv -n -- "$f" "$dir/${base//[ ,.()]}"; done' sh {} +
Observe que incluí um
echo
comando acima, como uma medida de “olhe antes de pular”. Se você executar o comando acima, ele mostrará todos osmv
comandos necessários. Se estiver tudo bem para você, execute o comando novamente com o “echo
” removido.
A propósito, o comando que você mostra na pergunta falhará se algum arquivo com um .
em seu nome estão em um diretório que possui um espaço em seu nome.