Назад | Перейти на главную страницу

BSD - рекурсивно удаляет символы, отличные от ascii, из всех файлов в каталоге

Я пытаюсь перенести кучу (300 ГБ +) файлов с диска FAT32 в мою файловую систему freeNas ZFS, но каждая команда, которую я ей задаю (tar, pax, mv, cp), выдает `` недопустимый аргумент '' при обнаружении не- Имя файла в формате ASCII - обычно это что-то, созданное под Windows, и читается что-то вроде "foo? S bar.mp3 ...", где? могло быть апострофом или чем-то подобным.

Может ли кто-нибудь помочь несколькими строками кода рекурсивно пройти по дереву каталогов и переименовать файлы, чтобы удалить недопустимые символы.

Очень признателен.

Переименовать можно ..

попробуйте что-нибудь вроде

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

вам может понадобиться cat -v для правильного отображения каких-либо странных символов без того, чтобы ваш терминал завис.

если это печатает приемлемые замены, измените -n на -v.

Тем не менее, похоже, что кодировка в вашей файловой системе неправильная (mount -o utf8?), Поскольку такого рода вещи действительно должны работать ...

Это один из правильных способов рекурсивного применения:

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

замените все эти символы на подчеркивание. Будьте осторожны, учитывает все пробелы.

почему это работает? пройдите этот тест:

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

(как видите, все файлы были изменены)

Использовать convmv для преобразования имен файлов, если они действительно неправильно закодированы. Вы должны в первую очередь предпочесть монтировать файловую систему с правильной кодировкой.

Замена подчеркиванием:

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

Попробуйте смонтировать файловую систему с параметром iocharset, установленным на используемую ею кодировку.

Из man mount в разделе «Варианты крепления для жира»:

   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.

См. Также в разделе «Параметры монтирования для 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).

и

   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.

Редактировать:

Извините, это был Linux, это для BSD (из 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.