BSD - Remove caracteres não-ascii de todos os arquivos em um diretório recursivamente

5

Estou tentando migrar um monte (300 GB +) de arquivos de uma unidade FAT32 para o meu sistema de arquivos freeNas ZFS, mas todo comando que eu lancei (tar, pax, mv, cp) lança um 'argumento inválido' quando encontra um nome de arquivo não-ASCII - geralmente é algo que foi criado no Windows e lê algo como "foo? s bar.mp3 ..." onde o? pode ter sido um apóstrofo ou algo semelhante.

Alguém pode ajudar com algumas linhas de código para percorrer recursivamente a árvore de diretórios e renomear arquivos para remover os caracteres ofensivos.

Muito apreciado.

    
por Dan 01.01.2010 / 22:24

5 respostas

0

Tente montar o sistema de arquivos com a opção iocharset definida para a codificação usada.

De man mount na seção "Opções de montagem para gordura":

   iocharset=value
          Character set to use for converting between 8 bit characters and
          16 bit Unicode characters. The default is iso8859-1.  Long file‐
          names are stored on disk in Unicode format.

Veja também na seção "Opções de montagem para vfat":

   uni_xlate
          Translate  unhandled  Unicode  characters  to  special   escaped
          sequences.   This lets you backup and restore filenames that are
          created with any Unicode characters. Without this option, a  '?'
          is used when no translation is possible. The escape character is
          ':' because it is otherwise illegal on the vfat filesystem.  The
          escape  sequence  that gets used, where u is the unicode charac‐
          ter, is: ':', (u & 0x3f), ((u>>6) & 0x3f), (u>>12).

e

   utf8   UTF8  is  the  filesystem safe 8-bit encoding of Unicode that is
          used by the console. It can be be  enabled  for  the  filesystem
          with this option or disabled with utf8=0, utf8=no or utf8=false.
          If 'uni_xlate' gets set, UTF8 gets disabled.

Editar:

Me desculpe, isso foi Linux, isso é para o BSD (de man mount_msdosfs :

 -L locale
     Specify locale name used for file name conversions for DOS and
     Win'95 names.  By default ISO 8859-1 assumed as local character
     set.

 -D DOS_codepage
     Specify the MS-DOS code page (aka IBM/OEM code page) name used
     for file name conversions for DOS names.
    
por 06.01.2010 / 14:53
7

Renomear pode fazer isso ..

tente algo como

find dir -depth -exec rename -n 's/[^[:ascii:]]/_/g' {} \; | cat -v

você pode precisar do gato -v para exibir corretamente quaisquer caracteres estranhos sem que seu terminal seja ferrado.

se isso imprimir substituições aceitáveis, altere o -n para -v.

Dito isto, parece que o conjunto de caracteres no seu sistema de arquivos está errado (mount -o utf8?), já que esse tipo de coisa deveria realmente funcionar ...

    
por 03.01.2010 / 00:53
2

Esta é uma maneira correta de aplicar recursivamente:

find . -depth -execdir rename 'y/[\:\;\>\<\@\$\#\&\(\)\?\\%\ ]/_/' {} \;

altere todos esses símbolos para sublinhado. Tenha cuidado, está considerando todos os espaços em branco.

por que funciona? faça este teste:

mkdir test

cd test

mkdir -p a$/b$/c$/d$ f%/g%/h%/i% j%/k%/l%/m%

find . -depth -execdir rename 'y/[\:\;\>\<\@\$\#\&\(\)\?\\%\ ]/_/' {} \;

ls -R

(como você pode ver, todos os arquivos foram alterados)

    
por 24.10.2012 / 02:54
1

Use convmv para converter os nomes dos arquivos, se eles forem realmente incorretamente codificado. Você deve preferir montar o sistema de arquivos com a codificação correta em primeiro lugar.

    
por 06.01.2010 / 15:34
0

Substituindo por sublinhados:

find . | perl -ane '{ if(m/[[:^ascii:]]/) { print } }' | rename -n 's/[^[:ascii:]]/_/g'
    
por 01.02.2012 / 11:34