BSD – 以recursion方式从目录中的所有文件中删除非ASCII字符

我试图从一个FAT32驱动器中将一大堆文件(300GB +)迁移到我的freeNas ZFS文件系统,但是当我遇到一个非法的文件系统时,我向它扔的每个命令(tar,pax,mv,cp)都会抛出一个“无效的参数” ASCII文件名 – 通常是在Windows下创build的东西,它读取“foo?s bar.mp3 …”的内容。 可能是一个撇号或这样的。

任何人都可以帮助几行代码recursion地通过目录树和重命名文件删除有问题的字符。

非常感激。

尝试安装文件系统的iocharset选项设置为它使用的编码。

从“Mount for fat”部分下的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. 

重命名可以做到这一点..

尝试类似的东西

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

您可能需要cat -v才能正确显示任何奇怪的字符,而不会让您的terminal受到干扰。

如果打印出可接受的replace,则将-n更改为-v。

这就是说,这听起来像你的文件系统上的字符集是错误的(mount -o utf8?),因为这样的事情应该真的有效…

这是recursion应用的一种正确的方法:

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

将所有这些符号更改为下划线。 要小心,正在考虑所有的空白。

为什么它的作品? 参加这个testing:

 mkdir test cd test mkdir -pa$/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'