Como renomear em massa arquivos com codificação inválida ou caracteres inválidos codificados em massa?

12

Eu tenho um servidor Debian e estou hospedando música para uma estação de rádio na internet. Eu tenho problemas com nomes de arquivos e caminhos porque muitos arquivos têm uma codificação inválida, por exemplo:

./music/Bändname - Some Title - additional Info/B�ndname - 07 - This Title Is Cörtain, The EncÃding Not.mp3

Idealmente, gostaria de remover tudo o que não seja letras A-Z / a-z ou números 0-9 ou traço - / underscore _ ... O resultado deve ser algo como isso:

./music/Bndname-SomeTitle-additionalInfo/Bndname-07-ThisTitleIsCrtain,TheEncdingNot.mp3

Como conseguir isso para um lote de muitos arquivos e diretórios?

Eu vi essa pergunta semelhante: bulk renomear (ou exibir corretamente) arquivos com caracteres especiais

Mas isso só corrige a codificação, eu preferiria uma abordagem mais rigorosa, conforme descrito acima.

    
por Afri 18.01.2013 / 11:49

3 respostas

12

Você será executado em alguns problemas se quiser renomear os diretórios e ao mesmo tempo. Renomear apenas um arquivo é bastante fácil. Mas você quer ter certeza de que os diretórios também sejam renomeados. Você não pode simplesmente mv Motörhead/Encöding Motorhead/Encoding , pois Motorhead não existirá no momento da chamada.

Portanto, precisamos de uma profundidade primeiro de todos os arquivos e pastas e, em seguida, renomeie apenas o arquivo ou a pasta atual. O seguinte funciona com GNU find e Bash 4.2.42 no meu OS X:

#!/usr/bin/env bash
find "$1" -depth -print0 | while IFS= read -r -d '' file; do
  d="$( dirname "$file" )"
  f="$( basename "$file" )"
  new="${f//[^a-zA-Z0-9\/\._\-]/}"
  if [ "$f" != "$new" ]      # if equal, name is already clean, so leave alone
  then
    if [ -e "$d/$new" ]
    then
      echo "Notice: \"$new\" and \"$f\" both exist in "$d":"
      ls -ld "$d/$new" "$d/$f"
    else
      echo mv "$file" "$d/$new"      # remove "echo" to actually rename things
    fi
  fi
done

Salve este script como rename.sh , torne-o executável com chmod +x rename.sh . Em seguida, chame como rename.sh /some/path . Resolva quaisquer colisões de nomes de arquivos (anúncios " Notice ").

Se você estiver absolutamente certo de que ele faz as substituições corretas, remova o echo do script para realmente renomear as coisas, em vez de simplesmente imprimir o que ele faz.

Por segurança, eu recomendaria testar isso em um pequeno subconjunto de arquivos primeiro.

Opções explicadas

Para explicar o que acontece aqui:

  • -depth garantirá que os diretórios sejam recursivos em profundidade primeiro, para que possamos "acumular" tudo desde o final. Normalmente, find atravessa de forma diferente (mas não em largura).
  • -print0 garante que a saída find seja delimitada por nulo, portanto, podemos lê-la com read -d '' na variável file . Isso nos ajuda a lidar com todos os tipos de nomes de arquivos estranhos, incluindo aqueles com espaços e até mesmo novas linhas.
  • Obteremos o diretório do arquivo com dirname . Não se esqueça de sempre citar suas variáveis corretamente, caso contrário, qualquer caminho com espaços ou caracteres globbing quebraria esse script.
  • Obteremos o nome do arquivo real (ou nome do diretório) com basename .
  • Em seguida, removemos qualquer caractere inválido de $f usando os recursos de substituição de string do Bash. Inválido significa qualquer coisa que não seja uma letra maiúscula ou minúscula, um dígito, uma barra ( \/ ), um ponto ( \. ), um sublinhado ou um hífen negativo.
  • Se $f já estiver limpo (o nome limpo é idêntico ao nome atual), pule-o.
  • Se o $new já existir no diretório $d (por exemplo, você tem arquivos com o nome resume e résumé no mesmo diretório), emita um aviso. Você não quer renomeá-lo, porque, em alguns sistemas, mv foo foo causa um problema. Caso contrário,
  • Finalmente renomeamos o arquivo original (ou diretório) para o novo nome

Como isso só funcionará na hierarquia mais profunda, renomear Motörhead/Encöding para Motorhead/Encoding será feito em duas etapas:

  1. mv Motörhead/Encöding Motörhead/Encoding
  2. mv Motörhead Motorhead

Isso garante que todas as substituições sejam feitas na ordem correta.

Arquivos de exemplo e execução de teste

Vamos supor que alguns arquivos em uma pasta base sejam chamados de test :

test
test/Motörhead
test/Motörhead/anöther_file.mp3
test/Motörhead/Encöding
test/Randöm
test/Täst
test/Täst/Töst
test/with space
test/with-hyphen.txt
test/work
test/work/resume
test/work/résumé
test/work/schedule

Aqui está a saída de uma execução no modo de depuração (com o echo na frente do mv ), ou seja, os comandos que seriam chamados e os avisos de colisão:

mv test/Motörhead/anöther_file.mp3 test/Motörhead/another_file.mp3
mv test/Motörhead/Encöding test/Motörhead/Encoding
mv test/Motörhead test/Motorhead
mv test/Randöm test/Random
mv test/Täst/Töst test/Täst/Tost
mv test/Täst test/Tast
mv test/with space test/withspace
Notice: "resume" and "résumé" both exist in test/work:
-rw-r—r--  …  …  test/work/resume
-rw-r—r--  …  …  test/work/résumé

Observe a ausência de mensagens para with-hyphen.txt , schedule e test em si.

    
por 18.01.2013 / 16:44
14

Eu sei que não é exatamente o que você queria, mas se você conhece a codificação original, talvez você possa usar convmv para alterar a codificação para UTF-8, o que deve corrigir a maioria dos problemas.

Isso funcionou para mim em uma pasta com alguns nomes de arquivos poloneses com codificação inválida:

convmv -f cp1250 -t utf8 -r .

Note que este comando não renomeia nada; Adicione a opção --notest para realmente renomear os arquivos.

    
por 30.08.2013 / 21:00
0

Eu sei, você perguntou sobre renomear.

Mas você pode evitar o problema com bastante facilidade usando softwares como o MusicBrainz Picard .

É capaz de identificar música (impressão digital de áudio), baixar todos os dados necessários (incluindo imagens de capa, quando disponíveis) do enorme MusicBrainz banco de dados e mover os arquivos para que sua coleção possa se encaixar em qualquer padrão desejado. Eu estou usando isso há anos e sempre funcionou perfeitamente com qualquer coisa de cirílico ao árabe; e claro (pelo menos para scripts baseados em latim) ele também pode fazer a conversão para ASCII.

Com essa abordagem, não importa realmente o quanto a sua coleção é realmente confusa / mal nomeada, contanto que os arquivos sejam legíveis e completos.

(Eu mencionei que é grátis? Tanto na liberdade de expressão quanto na cerveja grátis? Tanto o software quanto o banco de dados ..?)

    
por 16.10.2015 / 06:45