I need to write a file glob that will match all files except for those that are contained within a certain folder (e.g. all files except those contained within the high level folder foo/.
I've arrived at the following glob:
!(foo)/**/*
However, this glob doesn't seem to match on any files in Ruby's File.fnmatch (even with FNM_PATHNAME and FNM_DOTMATCH set to true.
Also, Ruby's glob interpreter seemed to have different behavior than JavaScript's:
JavaScript glob interpreter matches all strings
Ruby glob interpreter doesn't match any strings:
2.6.2 :027 > File.fnmatch("!(foo)/**/*", "hello/world.js")
=> false
2.6.2 :028 > File.fnmatch("!(foo)/**/*", "test/some/globs")
=> false
2.6.2 :029 > File.fnmatch("!(foo)/**/*", "foo/bar/something.txt")
=> false
CodePudding user response:
If you really need to use a glob then you can emulate the negation:
extglob = "{f,[^f]*,fo,f[^o]*,fo[^o]*,foo?*}/**/*"
File.fnmatch(extglob, "hello/world.js", File::FNM_EXTGLOB | File::FNM_PATHNAME)
#=> true
File.fnmatch(extglob, "test/some/globs", File::FNM_EXTGLOB | File::FNM_PATHNAME)
#=> true
File.fnmatch(extglob, "foo/bar/something.txt", File::FNM_EXTGLOB | File::FNM_PATHNAME)
#=> false
File.fnmatch(extglob, "food/bar/something.txt", File::FNM_EXTGLOB | File::FNM_PATHNAME)
#=> true
{f,[^f]*,fo,f[^o]*,fo[^o]*,foo?*} means:
- The string
f - Any string that doesn't start with
f - The string
fo - A string that starts with
fas long as the second letter isn'to - A string that starts with
foas long as the third letter isn'to - A string that starts with
fooas long as there is at least one more letter
