12
10

More than 5 years have passed since last update.

[Windows]ファイル検索で*と?以外のワイルドカード

Last updated at Posted at 2019-04-30

Windowsのワイルドカードでは、 *?がよく知られているが、それ以外にも存在することを知ったのでメモ。

tl;dr

  • >: 名前部分のみの任意の1文字に一致する
  • <: 名前部分のみの任意の文字列に一致する

詳細

FindFirstFileFindFirstFileExの説明には記載されていないが、ファイル名に使用できない文字を特別なパターンに割り当てているようだ。
シェル(コマンドプロンプト)で使用する文字と被っているので、APIを直接呼び出すアプリケーションからしか使用できない。

stackoverflow.comではこちらが詳しい。

FsRtlIsNameInExpression routine

Wildcard character Meaning
DOS_DOT(L'"') Matches either a period or zero characters beyond the name string.
名前文字列を超えたピリオドまたはゼロ文字のいずれかと一致します。
DOS_QM(L'>') Matches any single character or, upon encountering a period or end of name string, advances the expression to the end of the set of contiguous DOS_QMs.
任意の1文字に一致するか、ピリオドまたは名前文字列の終わりに遭遇すると、式を連続したDOS_QMのセットの終わりに進めます。
DOS_STAR(L'<') Matches zero or more characters until encountering and matching the final . in the name.
名前の最後の.に遭遇して一致するまで、0個以上の文字と一致します。

DOS_DOT はなぜ必要なのかはわからない。

パターン例

ファイル名 s*
s0 Match
s0.txt Match
sample Match
sample.txt Match
ファイル名 s<
s0 Match
s0.txt Unmatch
sample Match
sample.txt Unmatch
ファイル名 s*.txt
s0 Unmatch
s0.txt Match
sample Unmatch
sample.txt Match
ファイル名 s<.txt
s0 Unmatch
s0.txt Match
sample Unmatch
sample.txt Match

コード

#include <stdio.h>
#include <Windows.h>

void listup(LPCWSTR lpFileName)
{
    WIN32_FIND_DATA find_data;
    HANDLE h = FindFirstFile(lpFileName, &find_data);
    wprintf(L"searching...[%s]\n", lpFileName);

    if (h == INVALID_HANDLE_VALUE)
    {
        wprintf(L"not found.\n");
        return;
    }
    do
    {
        wprintf(L" found.[%s]\n", find_data.cFileName);
    } while (FindNextFile(h, &find_data));
    FindClose(h);
}

int main()
{
    listup(L"s*");
    listup(L"s*.txt");
    listup(L"s<");
    listup(L"s<.txt");
}
12
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10