我在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
# 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)