Home > OS >  Is there a way to write a glob pattern that matches all files except those in a folder?
Is there a way to write a glob pattern that matches all files except those in a folder?

Time:11-10

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:

  1. The string f
  2. Any string that doesn't start with f
  3. The string fo
  4. A string that starts with f as long as the second letter isn't o
  5. A string that starts with fo as long as the third letter isn't o
  6. A string that starts with foo as long as there is at least one more letter
  • Related