有没有办法在Linux下在Ruby中不区分大小写地打开文件?例如,给定字符串foo.txt
,我可以打开文件FOO.txt
吗?
一种可能的方法是读取目录中的所有文件名并手动搜索列表中的所需文件,但我正在寻找更直接的方法。
答案 0 :(得分:18)
虽然您无法使open
不区分大小写,但您可以非常简洁地编写您建议的目录搜索。 e.g。
filename = Dir.glob('foo.txt', File::FNM_CASEFOLD).first
if filename
# use filename here
else
# no matching file
end
请注意,documentation suggests that FNM_CASEFOLD can't be used with glob这似乎不正确或过时。
<强>替代强>
如果您担心使用FNM_CASEFOLD
,那么有几种选择:
filename = Dir.glob('*').find { |f| f.downcase == 'foo.txt' }
或编写一个小方法来为给定的文件名构建不区分大小写的glob:
def ci_glob(filename)
glob = ''
filename.each_char do |c|
glob += c.downcase != c.upcase ? "[#{c.downcase}#{c.upcase}]" : c
end
glob
end
irb(main):024:0> ci_glob('foo.txt')
=> "[fF][oO][oO].[tT][xX][tT]"
然后你可以这样做:
filename = Dir.glob(ci_glob('foo.txt')).first
答案 1 :(得分:1)
您可以将Dir.glob与FNM_CASEFOLD
标志一起使用,以获取除大小写之外与给定名称匹配的所有文件名列表。然后,您可以在结果数组上使用first
来获取任何结果,或者使用min_by
来获得与orignial最接近的情况匹配的结果。
def find_file(f)
Dir.glob(f, File::FNM_CASEFOLD).min_by do |f2|
f.chars.zip(f2.chars).count {|c1,c2| c1 != c2}
end
end
system "touch foo.bar"
system "touch Foo.Bar"
Dir.glob("FOO.BAR", File::FNM_CASEFOLD) #=> ["foo.bar", "Foo.Bar"]
find_file("FOO.BAR") #=> ["Foo.Bar"]