我在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Ú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
答案 0 :(得分:2)
NTFS内部编码始终是unicode。
因此,如果您使用NTFS作为文件系统,那么您拥有系统CP850并不重要。
尝试在ruby代码文件中设置# encoding: utf-8
答案 1 :(得分:0)
Pfew ..不知道我是否应该感到高兴,我终于找到了它,或者说红宝石让它变得如此困难。 无论如何,这是溶剂。
问题是当rubyscript在Windows7命令提示符(或shell)中获取参数时,它(在我的情况下)编码为CP1252,我不知道为什么。因此,如果我用CHCP 1252更改我的CP,脚本运行正常,但当然没有解决方案,所有特殊字符都打印错误。
解决方案:我告诉ruby编码IS CP1252并转换为我的语言环境CP(在我的情况下为CP850) 我希望可以检测CP1252而不是硬编码,这是一个更通用的解决方案。 有什么建议吗?
这里我用来测试它的程序,我传递参数“déjà.epub”,文件IS被重命名为这样。
a = ARGV[0].dup.encode(Encoding.locale_charmap)