Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open a file case-insensitively in Ruby under Linux

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.

like image 330
imgx64 Avatar asked Sep 06 '10 13:09

imgx64


People also ask

How do you do a case insensitive search in Linux?

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.

How do you use case insensitive in find command?

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 .

Which option will find string like in a file case insensitive?

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”.


1 Answers

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
like image 104
mikej Avatar answered Oct 27 '22 03:10

mikej