.NET에서 파일 와일드카드 사용

이 문서에서는 Microsoft.Extensions.FileSystemGlobbing NuGet 패키지로 파일 와일드카드를 사용하는 방법을 알아봅니다. GLOB은 와일드카드를 기반으로 파일 및 디렉터리 이름의 일치를 확인하기 위한 패턴을 정의하는 데 사용되는 용어입니다. 와일드카드 사용은 하나 이상의 GLOB 패턴을 정의하고 포함 또는 제외 일치에서 파일을 생성하는 동작입니다.

패턴

사용자 정의 패턴을 기반으로 파일 시스템에서 파일의 일치를 확인하려면 Matcher 개체를 인스턴스화하는 것으로 시작합니다. Matcher를 매개 변수 없이 인스턴스화할 수도 있고, 패턴을 파일 이름과 비교하기 위해 내부적으로 사용되는 System.StringComparison 매개 변수를 사용하여 인스턴스화할 수도 있습니다. Matcher는 다음과 같은 추가 메서드를 노출합니다.

결과에서 제외하거나 포함할 다양한 파일 이름 패턴을 추가하기 위해 AddExcludeAddInclude 메서드를 여러 번 호출할 수 있습니다. Matcher를 인스턴스화하고 패턴을 추가하면 Matcher.Execute 메서드를 사용하여 시작 디렉터리에서 일치 항목을 평가하는 데 사용됩니다.

확장 메서드

Matcher 개체에는 여러 확장 메서드가 있습니다.

다중 제외

다중 제외 패턴을 추가하려면 다음을 사용할 수 있습니다.

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

또는 MatcherExtensions.AddExcludePatterns(Matcher, IEnumerable<String>[])을 사용하여 단일 호출에서 다중 제외 패턴을 추가할 수 있습니다.

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

이 확장 메서드는 사용자를 대신하여 AddExclude를 호출하는 제공된 모든 패턴을 반복합니다.

다중 포함

다중 포함 패턴을 추가하려면 다음을 사용할 수 있습니다.

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

또는 MatcherExtensions.AddIncludePatterns(Matcher, IEnumerable<String>[])을 사용하여 단일 호출에 다중 포함 패턴을 추가할 수 있습니다.

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

이 확장 메서드는 사용자를 대신하여 AddInclude를 호출하는 제공된 모든 패턴을 반복합니다.

일치하는 모든 파일 가져오기

일치하는 모든 파일을 가져오려면 직접 또는 간접적으로 Matcher.Execute(DirectoryInfoBase)를 호출해야 합니다. 직접 호출하려면 검색 디렉터리를 사용해야 합니다.

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.

위의 C# 코드에서:

참고 항목

DirectoryInfoWrapper 형식은 Microsoft.Extensions.FileSystemGlobbing.Abstractions 네임스페이스에 정의되고 DirectoryInfo 형식은 System.IO 네임스페이스에 정의됩니다. 불필요한 using 문을 방지하려면 제공된 확장 메서드를 사용할 수 있습니다.

일치하는 파일을 나타내는 IEnumerable<string>을 생성하는 또 다른 확장 메서드가 있습니다.

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.

위의 C# 코드에서:

  • Matcher 개체를 인스턴스화합니다.
  • AddIncludePatterns(Matcher, IEnumerable<String>[])을 호출하여 포함할 여러 파일 이름 패턴을 추가합니다.
  • 검색 디렉터리 값을 선언하고 할당합니다.
  • searchDirectory 값이 제공되면 GetResultsInFullPath를 호출하여 일치하는 모든 파일을 IEnumerable<string>으로 생성합니다.

오버로드 일치

PatternMatchingResult 개체는 FilePatternMatch 인스턴스의 컬렉션을 나타내며 결과에 일치 항목, PatternMatchingResult.HasMatches가 있는지를 나타내는 boolean 값을 노출합니다.

Matcher 인스턴스를 사용하면 다양한 Match 오버로드를 호출하여 패턴 일치 결과를 얻을 수 있습니다. Match 메서드는 일치를 평가할 파일 또는 파일 컬렉션을 제공하는 호출자의 책임을 반전합니다. 즉, 호출자는 일치를 확인할 파일을 전달해야 합니다.

Important

Match 오버로드를 사용하는 경우 파일 시스템 I/O가 관련되지 않습니다. 모든 파일 와일드카드 사용은 matcher 인스턴스의 포함 및 제외 패턴을 사용하여 메모리에서 수행됩니다. Match 오버로드의 매개 변수는 정규화된 경로일 필요가 없습니다. 지정되지 않은 경우 현재 디렉터리(Directory.GetCurrentDirectory())가 사용됩니다.

단일 파일의 일치를 확인하려면:

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

PatternMatchingResult result = matcher.Match("file.md");

위의 C# 코드에서:

  • 임의의 디렉터리 깊이에서 파일 확장명이 .md인 모든 파일의 일치를 확인합니다.
  • file.md라는 이름의 파일이 현재 디렉터리의 하위 디렉터리에 있는 경우:
    • result.HasMatchestrue가 됩니다.
    • result.Files의 일치 항목은 하나가 됩니다.

추가 Match 오버로드는 비슷한 방식으로 작동합니다.

패턴 형식

AddExcludeAddInclude 메서드에 지정된 패턴은 다음 형식을 사용하여 여러 파일 또는 디렉터리의 일치를 확인할 수 있습니다.

  • 정확한 디렉터리 또는 파일 이름

    • some-file.txt
    • path/to/file.txt
  • 구분 문자를 포함하지 않는 0부터 여러 개의 문자를 나타내는 파일 및 디렉터리 이름의 와일드카드 *.

    설명
    *.txt 파일 확장명이 .txt인 모든 파일.
    *.* 확장이 있는 모든 파일.
    * 최상위 디렉터리에 있는 모든 파일.
    .* ‘.’으로 시작하는 파일 이름.
    *word* 파일 이름에 ‘word’가 있는 모든 파일.
    readme.* 임의의 파일 확장자명과 함께 ‘readme’라는 이름의 모든 파일.
    styles/*.css ‘styles/’ 디렉터리에서 확장명이 ‘.css’인 모든 파일.
    scripts/*/* ‘scripts/’의 모든 파일 또는 ‘scripts/’ 아래 한 수준 하위 디렉터리의 모든 파일.
    images*/* 이름이 ‘images’이거나 ‘images’로 시작하는 폴더의 모든 파일.
  • 임의의 디렉터리 깊이(/**/).

    설명
    **/* 임의의 하위 디렉터리에 있는 모든 파일.
    dir/ ‘dir/’ 아래 임의의 하위 디렉터리에 있는 모든 파일.
    dir/**/* ‘dir/’ 아래 임의의 하위 디렉터리에 있는 모든 파일.
  • 상대 경로.

    형제 수준에서 “shared”라는 디렉터리의 모든 파일에 대해 Matcher.Execute(DirectoryInfoBase)에 지정된 기본 디렉터리와 일치를 확인하려면 ../shared/*를 사용합니다.

예제

다음 예제 디렉터리와 해당 폴더 내의 각 파일을 고려해 보겠습니다.

📁 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

일부 파일 확장명은 대문자이고 나머지 파일 확장명은 소문자입니다. 기본적으로 StringComparer.OrdinalIgnoreCase가 사용됩니다. 서로 다른 문자열 비교 동작을 지정하려면 Matcher.Matcher(StringComparison) 생성자를 사용합니다.

대/소문자에 관계없이 파일 확장명이 .md 또는 .mtext인 모든 markdown 파일을 가져오려면:

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

foreach (string file in matcher.GetResultsInFullPath("parent"))
{
    Console.WriteLine(file);
}

애플리케이션을 실행하면 다음과 유사한 결과가 출력됩니다.

C:\app\parent\file.md
C:\app\parent\README.md
C:\app\parent\child\file.MD
C:\app\parent\child\more.md
C:\app\parent\child\sample.mtext
C:\app\parent\child\grandchild\file.md

임의의 깊이에서 assets 디렉터리에 있는 파일을 가져오려면:

Matcher matcher = new();
matcher.AddInclude("**/assets/**/*");

foreach (string file in matcher.GetResultsInFullPath("parent"))
{
    Console.WriteLine(file);
}

애플리케이션을 실행하면 다음과 유사한 결과가 출력됩니다.

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

임의의 깊이에서 디렉터리 이름에 child라는 단어가 포함되어 있고 파일 확장명이 .md, .text 또는 .mtext가 아닌 파일을 가져오려면:

Matcher matcher = new();
matcher.AddInclude("**/*child/**/*");
matcher.AddExcludePatterns(
    new[]
    {
        "**/*.md", "**/*.text", "**/*.mtext"
    });

foreach (string file in matcher.GetResultsInFullPath("parent"))
{
    Console.WriteLine(file);
}

애플리케이션을 실행하면 다음과 유사한 결과가 출력됩니다.

C:\app\parent\child\index.js
C:\app\parent\child\assets\image.png
C:\app\parent\child\assets\image.svg
C:\app\parent\child\grandchild\style.css

참고 항목