Is there a way to open a file case-insensitively in Ruby under Linux? For example, given the string foo.txt
, can I open the file FOO.txt
?
One possible way would be reading all the filenames in the directory and manually search the list for the required file, but I'm looking for a more direct method.
Case-insensitive file searching with the find command The key to that case-insensitive search is the use of the -iname option, which is only one character different from the -name option. The -iname option is what makes the search case-insensitive.
This pattern of adding -i before an option follows for other find options too. Ex: -name to search for a name, and -iname to make it case-insensitive. -path to search for a path, and -ipath to make it case-insensitive. I mention using -ipath in my answer here: Stack Overflow: How to exclude a directory in find .
Case insensitive search : The -i option enables to search for a string case insensitively in the given file. It matches the words like “UNIX”, “Unix”, “unix”.
Whilst you can't make open
case insensitive you can write the directory search you suggested quite concisely. e.g.
filename = Dir.glob('foo.txt', File::FNM_CASEFOLD).first
if filename
# use filename here
else
# no matching file
end
Note that whilst the documentation suggests that FNM_CASEFOLD can't be used with glob this appears to be incorrect or out of date.
Alternatives
If you're concerned about using FNM_CASEFOLD
then a couple of alternatives are:
filename = Dir.glob('*').find { |f| f.downcase == 'foo.txt' }
or write a little method to build a case insensitive glob for a given filename:
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]"
and then you can do:
filename = Dir.glob(ci_glob('foo.txt')).first
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With