Ruby:用特殊字符重命名文件



我在ruby版本1.9.3p0中有这个程序,它根据正则表达式条件重命名从shell传递的文件(发送到)。正常工作,除非文件名中有特殊字符。

ruby RegExpRename.rb "32. Esther Verhoef - Déjà vu.epub"

给错误

/RegExpRename.rb:29:in `rename': No such file or directory - (32. Esther Verhoef - DÚjÓ vu.epub, test) (Errno::ENOENT)
from C:/Users/peter/AppData/Roaming/Microsoft/Windows/SendTo/RegExpRename.rb:29:in `block in <main>'
from C:/Users/peter/AppData/Roaming/Microsoft/Windows/SendTo/RegExpRename.rb:18:in `each'
from C:/Users/peter/AppData/Roaming/Microsoft/Windows/SendTo/RegExpRename.rb:18:in `<main>'

编码是罪魁祸首,我的windows cp是CP850, d jjo改为DÚjÓ我不知道怎么解决这个问题,请帮帮我。这里的程序

# encoding: CP850
require 'find'
require 'fileutils'
require 'Win32API'
def get_long_win32_filename(short_name)
  max_path = 1024
  long_name = " " * max_path
  lfn_size = Win32API.new("kernel32", "GetLongPathName", ['P','P','L'],'L').call(short_name, long_name, max_path)
  return (1..max_path).include?(lfn_size) ? long_name[0..lfn_size-1] :  short_name
end
ARGV.each do|a|
  long = get_long_win32_filename(a)
  result = long.gsub(/(w+)s*,s*([^-]+)s*-s*(.+.[a-zA-Z]{3,4})/i, "\2 \1 - \3")
  if result == long
    result = long.gsub(/(d+. +)(.*)/i, "\2")
  end
  if result != long
    if File.exist?(result)
      puts "File #{result} already exists.  Not renaming."
    else
      File.rename(a, long)
      puts long + " ===> " + result
    end
  else
    puts long_name + " don't have to be renamed"
  end
end
sleep 15

NTFS内部编码始终为unicode。

所以,如果你使用NTFS作为文件系统,那么你的系统是CP850就没关系了。

尝试在ruby代码文件中设置# encoding: utf-8

我不知道我该为我终于找到它而高兴,还是为ruby让它变得如此困难而难过。总之,这就是解决办法。

问题是当rubyscript在Windows7命令提示符(或shell)中获得参数时,它会得到这个(在我的情况下)编码为CP1252,我不知道为什么。因此,如果我用CHCP 1252更改我的CP,脚本运行良好,但这当然不是解决方案,所有特殊字符都打印错误。

解决方案:我告诉ruby编码是CP1252,并将其转换为我的区域设置CP(在我的情况下是CP850)我希望CP1252可以被检测到,而不是硬编码,所以这是一个更通用的解决方案。有什么建议吗?

在这里,我用来测试这个的程序,我传递了参数" dj。

a = ARGV[0].dup.encode(Encoding.locale_charmap)

最新更新