Movatterモバイル変換


[0]ホーム

URL:


Skip to main content

This browser is no longer supported.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Download Microsoft EdgeMore info about Internet Explorer and Microsoft Edge
Table of contentsExit editor mode

File globbing in .NET

Feedback

In this article

In this article, you'll learn how to use file globbing with theMicrosoft.Extensions.FileSystemGlobbing NuGet package. Aglob is a term used to define patterns for matching file and directory names based on wildcards. Globbing is the act of defining one or more glob patterns, and yielding files from either inclusive or exclusive matches.

Patterns

To match files in the file system based on user-defined patterns, start by instantiating aMatcher object. AMatcher can be instantiated with no parameters, or with aSystem.StringComparison parameter, which is used internally for comparing patterns to file names. TheMatcher exposes the following additive methods:

BothAddExclude andAddInclude methods can be called any number of times, to add various file name patterns to either exclude or include from results. Once you've instantiated aMatcher and added patterns, it's then used to evaluate matches from a starting directory with theMatcher.Execute method.

Extension methods

TheMatcher object has several extension methods.

Multiple exclusions

To add multiple exclude patterns, you can use:

Matcher matcher = new();matcher.AddExclude("*.txt");matcher.AddExclude("*.asciidoc");matcher.AddExclude("*.md");

Alternatively, you can use theMatcherExtensions.AddExcludePatterns(Matcher, IEnumerable<String>[]) to add multiple exclude patterns in a single call:

Matcher matcher = new();matcher.AddExcludePatterns(new [] { "*.txt", "*.asciidoc", "*.md" });

This extension method iterates over all of the provided patterns callingAddExclude on your behalf.

Multiple inclusions

To add multiple include patterns, you can use:

Matcher matcher = new();matcher.AddInclude("*.txt");matcher.AddInclude("*.asciidoc");matcher.AddInclude("*.md");

Alternatively, you can use theMatcherExtensions.AddIncludePatterns(Matcher, IEnumerable<String>[]) to add multiple include patterns in a single call:

Matcher matcher = new();matcher.AddIncludePatterns(new[] { "*.txt", "*.asciidoc", "*.md" });

This extension method iterates over all of the provided patterns callingAddInclude on your behalf.

Get all matching files

To get all matching files, you have to callMatcher.Execute(DirectoryInfoBase) either directly or indirectly. To call it directly, you need a search directory:

Matcher matcher = new();matcher.AddIncludePatterns(new[] { "*.txt", "*.asciidoc", "*.md" });string searchDirectory = "../starting-folder/";PatternMatchingResult result = matcher.Execute(    new DirectoryInfoWrapper(        new DirectoryInfo(searchDirectory)));// Use result.HasMatches and results.Files.// The files in the results object are file paths relative to the search directory.

The preceding C# code:

Note

TheDirectoryInfoWrapper type is defined in theMicrosoft.Extensions.FileSystemGlobbing.Abstractions namespace, and theDirectoryInfo type is defined in theSystem.IO namespace. To avoid unnecessaryusing directives, you can use the provided extension methods.

There is another extension method that yields anIEnumerable<string> representing the matching files:

Matcher matcher = new();matcher.AddIncludePatterns(new[] { "*.txt", "*.asciidoc", "*.md" });string searchDirectory = "../starting-folder/";IEnumerable<string> matchingFiles = matcher.GetResultsInFullPath(searchDirectory);// Use matchingFiles if there are any found.// The files in this collection are fully qualified file system paths.

The preceding C# code:

  • Instantiates aMatcher object.
  • CallsAddIncludePatterns(Matcher, IEnumerable<String>[]) to add several file name patterns to include.
  • Declares and assigns the search directory value.
  • CallsGetResultsInFullPath given thesearchDirectory value to yield all matching files as aIEnumerable<string>.

Match overloads

ThePatternMatchingResult object represents a collection ofFilePatternMatch instances, and exposes aboolean value indicating whether the result has matches—PatternMatchingResult.HasMatches.

With aMatcher instance, you can call any of the variousMatch overloads to get a pattern matching result. TheMatch methods invert the responsibility on the caller to provide a file or a collection of files in which to evaluate for matches. In other words, the caller is responsible for passing the file to match on.

Important

When using any of theMatch overloads, there is no file system I/O involved. All of the file globbing is done in memory with the include and exclude patterns of thematcher instance. The parameters of theMatch overloads do not have to be fully qualified paths. The current directory (Directory.GetCurrentDirectory()) is used when not specified.

To match a single file:

Matcher matcher = new();matcher.AddInclude("**/*.md");PatternMatchingResult result = matcher.Match("file.md");

The preceding C# code:

  • Matches any file with the.md file extension, at an arbitrary directory depth.
  • If a file namedfile.md exists in a subdirectory from the current directory:
    • result.HasMatches would betrue.
    • andresult.Files would have one match.

The additionalMatch overloads work in similar ways.

Ordered evaluation of include/exclude

By default, the matcher evaluatesall include patterns first, then appliesall exclude patterns, regardless of the order in which you added them. This means you can't re-include files that were previously excluded.

Starting in version 10 of the📦 Microsoft.Extensions.FileSystemGlobbing package, you can opt intoordered evaluation, where includes and excludes are processed exactly in the sequence they were added:

using Microsoft.Extensions.FileSystemGlobbing;// Preserve the order of patterns when matching.Matcher matcher = new(preserveFilterOrder: true);matcher.AddInclude("**/*");                // include everythingmatcher.AddExclude("logs/**/*");           // exclude logsmatcher.AddInclude("logs/important/**/*"); // re-include important logsvar result = matcher.Execute(new DirectoryInfoWrapper(new DirectoryInfo(root)));foreach (var file in result.Files){    Console.WriteLine(file.Path);}

In this mode, patterns are applied one after another:

  • **/* adds all files.
  • logs/**/* filters out anything inlogs/.
  • logs/important/**/* adds back only files underlogs/important/.

Existing code that uses the default constructor will continue to run with the original "all includes, then all excludes" behavior.

Pattern formats

The patterns that are specified in theAddExclude andAddInclude methods can use the following formats to match multiple files or directories.

  • Exact directory or file name

    • some-file.txt
    • path/to/file.txt
  • Wildcards* in file and directory names that represent zero to many characters not including separator characters.

    ValueDescription
    *.txtAll files with.txt file extension.
    *.*All files with an extension.
    *All files in top-level directory.
    .*File names beginning with '.'.
    *word*All files with 'word' in the filename.
    readme.*All files named 'readme' with any file extension.
    styles/*.cssAll files with extension '.css' in the directory 'styles/'.
    scripts/*/*All files in 'scripts/' or one level of subdirectory under 'scripts/'.
    images*/*All files in a folder with name that is or begins with 'images'.
  • Arbitrary directory depth (/**/).

    ValueDescription
    **/*All files in any subdirectory.
    dir/All files in any subdirectory under 'dir/'.
    dir/**/*All files in any subdirectory under 'dir/'.
  • Relative paths.

    To match all files in a directory named "shared" at the sibling level to the base directory given toMatcher.Execute(DirectoryInfoBase), use../shared/*.

Examples

Consider the following example directory, and each file within its corresponding folder.

📁 parent│    file.md│    README.md│└───📁 child    │    file.MD    │    index.js    │    more.md    │    sample.mtext    │    ├───📁 assets    │        image.png    │        image.svg    │    └───📁 grandchild             file.md             style.css             sub.text

Tip

Some file extensions are in uppercase, while others are in lowercase. By default,StringComparer.OrdinalIgnoreCase is used. To specify different string comparison behavior, use theMatcher.Matcher(StringComparison) constructor.

To get all of the markdown files, where the file extension is either.md or.mtext, regardless of character case:

Matcher matcher = new();matcher.AddIncludePatterns(new[] { "**/*.md", "**/*.mtext" });foreach (string file in matcher.GetResultsInFullPath("parent")){    Console.WriteLine(file);}

Running the application would output results similar to the following:

C:\app\parent\file.mdC:\app\parent\README.mdC:\app\parent\child\file.MDC:\app\parent\child\more.mdC:\app\parent\child\sample.mtextC:\app\parent\child\grandchild\file.md

To get any files in anassets directory at an arbitrary depth:

Matcher matcher = new();matcher.AddInclude("**/assets/**/*");foreach (string file in matcher.GetResultsInFullPath("parent")){    Console.WriteLine(file);}

Running the application would output results similar to the following:

C:\app\parent\child\assets\image.pngC:\app\parent\child\assets\image.svg

To get any files where the directory name contains the wordchild at an arbitrary depth, and the file extensions are not.md,.text, or.mtext:

Matcher matcher = new();matcher.AddInclude("**/*child/**/*");matcher.AddExcludePatterns(    new[]    {        "**/*.md", "**/*.text", "**/*.mtext"    });foreach (string file in matcher.GetResultsInFullPath("parent")){    Console.WriteLine(file);}

Running the application would output results similar to the following:

C:\app\parent\child\index.jsC:\app\parent\child\assets\image.pngC:\app\parent\child\assets\image.svgC:\app\parent\child\grandchild\style.css

See also

Collaborate with us on GitHub
The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, seeour contributor guide.

Feedback

Was this page helpful?

YesNoNo

Need help with this topic?

Want to try using Ask Learn to clarify or guide you through this topic?

Suggest a fix?

  • Last updated on

In this article

Was this page helpful?

YesNo
NoNeed help with this topic?

Want to try using Ask Learn to clarify or guide you through this topic?

Suggest a fix?