6

I want to check if pattern with wildcards, e.g. /var/data/**/*.xml is matching to any file or directory on the disk.

Obviously I could use Dir.glob but it is very slow when there are millions of files because it is too eager - it returns all files matching the pattern while I only need to know if there is any.

Is there any way I could check that?

synek317
  • 749
  • 2
  • 7
  • 22
  • http://stackoverflow.com/questions/3498539/searching-a-folder-and-all-of-its-subfolders-for-files-of-a-certain-type – JLB Jan 16 '17 at 15:32

1 Answers1

5

Ruby-only

You could use Find, find and find :D.

I couldn't find any other File/Dir method that returns an Enumerator.

require 'find'
Find.find("/var/data/").find{|f| f=~/\.xml$/i }
#=> first xml file found inside "/var/data". nil otherwise
# or
Find.find("/var/data/").find{|f| File.extname(f).downcase == ".xml" }

If you really just want a boolean :

require 'find'
Find.find("/var/data/").any?{|f| f=~/\.xml$/i }

Note that if "/var/data/" exists but there is no .xml file inside it, this method will be at least as slow as Dir.glob.

As far as I can tell :

Dir.glob("/var/data/**/*.xml"){|f| break f}

creates a complete array first before returning its first element.

Bash-only

For a bash-only solution, you could use :

Community
  • 1
  • 1
Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
  • I'm afraid that `find` is not a solution for me. Path pattern that I have to check is in fact entered by the user and later passed to `find` shell command. The final effect that I want to achieve is to avoid `no such file or directory` error when executing `find` (from shell, not ruby `Find.find`) – synek317 Jan 16 '17 at 20:10
  • 1
    Got it. http://stackoverflow.com/questions/6363441/check-if-a-file-exists-with-wildcard-in-shell-script or http://unix.stackexchange.com/questions/79301/test-if-there-are-files-matching-a-pattern-in-order-to-execute-a-script might help you – Eric Duminil Jan 16 '17 at 21:50
  • 1
    http://stackoverflow.com/questions/2937407/test-whether-a-glob-has-any-matches-in-bash It looks like shell `find` might be the best option, followed by `compgen`. – Eric Duminil Jan 16 '17 at 21:55
  • Thank you, `compgen` works very well. It is not perfect, as it is bash-only solution, but fortunately it is available on all machines that I'm using. – synek317 Jan 17 '17 at 09:45