1. ホーム
  2. batch-file

[解決済み】WindowsのFINDSTRコマンドの文書化されていない機能や制限事項は何ですか?

2022-04-30 04:36:56

質問

WindowsのFINDSTRコマンドは、ひどい文書化されています。非常に基本的なコマンドラインヘルプは FINDSTR /? または HELP FINDSTR しかし、これは非常に不十分なものです。オンラインにはもう少し詳しいドキュメントが https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/findstr .

FINDSTRの機能や制限には、ドキュメントに書かれていないものも多くあります。また、予備知識および/または注意深い実験なしには、それらを予想することはできませんでした。

そこで質問なのですが FINDSTRの文書化されていない機能と制限とは何ですか?

この質問の目的は、文書化されていない多くの機能のワンストップリポジトリを提供することで、そうすることです。

A) 開発者は、そこにある機能を最大限に活用することができます。

B) 開発者は、動作するはずのものがなぜ動作しないのかと、時間を無駄にすることがない。

既存のドキュメントを把握した上で回答してください。もしその情報がHELPでカバーされているならば、ここに属するものではありません。

また、ここはFINDSTRの面白い使い方を紹介する場所でもありません。もし論理的な人が、ドキュメントに基づいてFINDSTRの特定の使い方の動作を予想できたとしても、それはここにふさわしくありません。

同じように、もし論理的な人が、既存の回答に含まれる情報に基づいて特定の使用法の動作を予想できたとしても、やはりそれはここに属するものではありません。

どのように解決するのですか?

前置き

この回答にある情報の多くは、Vistaマシンで行った実験に基づいて収集されたものです。特に明記されていない限り、他のWindowsのバージョンに適用されるかどうかは確認していません。

FINDSTRの出力

ドキュメントにはFINDSTRの出力についての説明は一切ありません。マッチした行が出力されるという事実をほのめかしているだけで、それ以上のことは書かれていません。

マッチング行の出力形式は以下の通りです。

ファイル名:行番号:行オフセット:テキスト

ここで

ファイル名です。 = 一致した行を含むファイルの名前です。要求が明示的に一つのファイルに対して行われた場合、 あるいはパイプ入力やリダイレクトされた入力を検索する場合、 ファイル名は表示されません。印刷されるとき、fileNameは常に提供されたすべてのパス情報を含みます。を指定すると、追加のパス情報が追加されます。 /S オプションが使用されています。印刷されるパスは常に指定されたパスからの相対パスであり、指定されていない場合はカレントディレクトリからの相対パスとなります。

注意 - 複数のファイルを検索する場合、ファイル名のプレフィクスを回避するために 非標準(かつ文書化も不十分)のワイルドカードである <> . これらのワイルドカードがどのように機能するかについての正確なルールは、次のとおりです。 こちら . 最後に、これを見ることができます。 非標準のワイルドカードがFINDSTRでどのように機能するかの例 .

行番号です。 = 一致した行の行番号を10進数で表し、1が入力の1行目を表します。以下の場合のみ表示される。 /N オプションが指定されています。

lineOffsetを指定します。 = 一致する行の先頭の10進数バイトオフセットで、0は1行目の1文字を表します。以下の場合のみ表示される。 /O オプションが指定されている。これは ではなく は、その行の中でのマッチのオフセットです。これは、ファイルの先頭から行の先頭までのバイト数である。

テキスト = 一致した行のバイナリ表現で、<CR> および/または <LF> が含まれます。バイナリ出力には何も残らないので、すべての行にマッチするこの例は、元のファイルの正確なバイナリコピーを生成します。

FINDSTR "^" FILE >FILE_COPY

Aオプションは、fileName:、lineNumber:、lineOffset:の出力の色のみを設定します。 一致する行のテキストは、常に現在のコンソールの色で出力されます。Aオプションは、出力がコンソールに直接表示される場合のみ有効です。Aオプションは、出力がファイルにリダイレクトされたり、パイプに通されたりしている場合は、効果がありません。詳細は 2018-08-18編集 Aaciniさんの回答で には、出力がCONにリダイレクトされた場合のバグ動作が記載されています。

XPでは、ほとんどの制御文字と多くの拡張ASCII文字がドットとして表示されます。

XPのFINDSTRは、マッチする行の印字不可能な制御文字のほとんどを画面上のドット(ピリオド)として表示します。0x09 Tab, 0x0A LineFeed, 0x0B Vertical Tab, 0x0C Form Feed, 0x0D Carriage Return のような制御文字は例外です。

XP FINDSTRは、いくつかの拡張ASCII文字もドットに変換します。XP でドットとして表示される拡張 ASCII 文字は、コマンドラインで供給されたときに変換されるものと同じです。このため コマンドラインパラメータの文字数制限 - 拡張ASCII変換" セクションをご覧ください。

XPでは、パイプ出力、ファイルへのリダイレクト、FOR IN()節内では、制御文字と拡張ASCIIはドットに変換されません。

Vista と Windows 7 は、すべての文字を常にそれ自体として表示し、ドットとして表示することはありません。

リターンコード(ERRORLEVEL)

  • 0 (成功)
    • 少なくとも1つのファイルの少なくとも1行にマッチが見つかりました。
  • 1 (失敗)
    • どのファイルのどの行にも一致するものが見つかりませんでした。
    • で指定された色は無効です。 /A:xx オプション
  • 2 (エラー)
    • 互換性のないオプション /L/R の両方が指定されています。
    • の後に引数がありません。 /A: , /F: , /C: , /D: または /G:
    • で指定されたファイル /F:file または /G:file 見つからない
  • 255 (エラー)

検索対象となるデータの出所 (Windows 7でのテストに基づき更新しました。)

Findstrは、以下のいずれかのソースからしかデータを検索できません。

  • 引数として指定されたファイル名と /F:file オプションで指定します。

  • リダイレクトによる標準入力 findstr "searchString" <file

  • パイプからのデータストリーム type file | findstr "searchString"

引数/オプションはリダイレクトより優先され、パイプされたデータより優先される。

ファイル名の引数と /F:file を組み合わせることができます。複数のファイル名引数を使用することができる。もし複数の /F:file オプションが指定された場合、最後に指定されたものだけが使用されます。ファイル名の引数にはワイルドカードが使用できますが /F:file .

検索文字列のソース (Windows 7でのテストに基づき更新しました。)

/G:file/C:string オプションは組み合わせることができます。複数の /C:string を指定することができる。複数の /G:file オプションが指定された場合、最後に指定されたものだけが使用されます。もし、どちらかの /G:file または /C:string を使用した場合、オプション以外のすべての引数は検索対象ファイルとみなされます。もし /G:file または /C:string を使用した場合、最初の非オプション引数は、スペースで区切られた検索語のリストとして扱われます。

を使用する場合、ファイル名はファイル内で引用してはいけません。 /F:FILE オプションで指定します。

ファイル名には、スペースやその他の特殊文字が含まれることがあります。ほとんどのコマンドは、そのようなファイル名を引用符で囲むことを要求します。しかし、FINDSTR /F:files.txt オプションは、files.txt内のファイル名を引用符で囲んではならないことを要求しています。ファイル名が引用されている場合、ファイルは見つかりません。

BUG - 8.3の短いファイル名では、このバグが発生する可能性があります。 /D/S オプション

すべてのWindowsコマンドと同様に、FINDSTRは、検索するファイルを探すときに、長い名前と短い8.3名の両方に一致させようとします。現在のフォルダーに次のような空でないファイルがあると仮定します。

b1.txt
b.txt2
c.txt

次のコマンドを実行すると、3つのファイルすべてが正常に検出されます。

findstr /m "^" *.txt

b.txt2 は対応する短い名前であるため、マッチします。 B9F64~1.TXT がマッチします。これは、他のすべてのWindowsコマンドの動作と一致する。

しかし /D/S オプションを指定すると、以下のコマンドは b1.txt

findstr /m /d:. "^" *.txt
findstr /m /s "^" *.txt

このバグにより b.txt2 の後にソートされたすべてのファイル名と同様に、検出されません。 b.txt2 を同じディレクトリに配置します。のような、前にソートされる追加のファイル a.txt が見つかります。後にソートされる追加ファイル、たとえば d.txt は、バグが発生した時点で見逃されます。

検索された各ディレクトリは独立して扱われます。例えば /S オプションは、親フォルダでファイルが見つからなかった後、子フォルダでの検索を正常に開始しますが、バグにより子フォルダで短いファイル名が見つからないと、その子フォルダ内の後続のファイルもすべて見つからないことになります。

NTFS 8.3の名前生成を無効にしているマシンで同じファイル名を作成した場合、コマンドはバグフリーで動作します。もちろん b.txt2 は検出されないが c.txt はちゃんと見つかります。

すべての短い名前がバグを誘発するわけではありません。私が見たバグのある動作のすべての例は、3文字より長い拡張子で、8.3名を必要としない通常の名前と同じ始まりの短い8.3名を含んでいます。

XP、Vista、Windows 7で不具合を確認しています。

印刷不可能な文字と /P オプション

/P オプションは、FINDSTRが以下の10進バイトコードのいずれかを含むファイルをスキップするようにします。

0-7, 14-25, 27-31.

別の言い方をすれば /P オプションは、印字不可能な制御文字を含むファイルのみをスキップします。制御文字は、31(0x1F)以下のコードです。FINDSTRは以下の制御文字を印刷可能な文字として扱います。

 8  0x08  backspace
 9  0x09  horizontal tab
10  0x0A  line feed
11  0x0B  vertical tab
12  0x0C  form feed
13  0x0D  carriage return
26  0x1A  substitute (end of text)

その他の制御文字はすべて印刷不可能な文字として扱われ、その存在によって /P オプションはファイルをスキップします。

パイプラインとリダイレクトされた入力には <CR><LF> 付加される

入力がパイプで送られてきて、ストリームの最後の文字が <LF> を自動的に追加します。 <CR><LF> を入力に追加します。XP、Vista、Windows 7で確認済みです。 (以前はWindowsのパイプが入力の修正を行っていると考えていましたが、実際にはFINDSTRが修正を行っていることがわかりました)

Vistaでのリダイレクト入力も同様です。リダイレクト入力として使われるファイルの最後の文字が <LF> を自動的に追加します。 <CR><LF> を入力に追加します。ただし、XPとWindows 7はリダイレクトされた入力を変更しない。

XP と Windows 7 では、リダイレクトされた入力の末尾が <LF>

これは、XPとWindows 7の厄介な"機能"です。リダイレクトされた入力として使用されるファイルの最後の文字が <LF> FINDSTRは、リダイレクトされたファイルの最後に到達すると、無期限にハングします。

パイプラインデータの最終行が一文字の場合、無視されることがあります。

入力がパイプで行われ、最終行が1文字で構成され、その後に <LF> であれば、FINDSTRは最後の行を完全に無視する。

例 - 最初のコマンドで、1文字で <LF> しかし、2文字の2番目のコマンドと、1文字で終端改行がある3番目のコマンドは正常に動作します。

> set /p "=x" <nul | findstr "^"

> set /p "=xx" <nul | findstr "^"
xx

> echo x| findstr "^"
x

DosTipsユーザーであるSponge Bellyさんからの報告です。 新しいfindstrのバグ . XP、Windows 7、Windows 8で確認。Vistaはまだ聞いていない。(Vistaはまだ聞いていません(私はもうテストするためにVistaを持っていません)。

オプションの構文

オプションの文字は大文字と小文字を区別しないので /i/I は等価である。

オプションの前には、以下のいずれかを付けることができます。 / または - オプションは、1つの / または - . ただし、連結されたオプションリストには、OFFやF:などの多文字のオプションを最大1つまで含めることができ、多文字のオプションはリストの最後のオプションでなければなりません。

以下はすべて、"hello" と "goodbye" の両方を任意の順序で含む行に対する大文字小文字を区別しない正規検索を表現する方法と同等です。

  • /i /r /c:"hello.*goodbye" /c:"goodbye.*hello"

  • -i -r -c:"hello.*goodbye" /c:"goodbye.*hello"

  • /irc:"hello.*goodbye" /c:"goodbye.*hello"

オプションは引用することもできます。そのため /i , -i , "/i""-i" はすべて等価です。同様に /c:string , "/c":string , "/c:"string"/c:string" はすべて等価です。

検索文字列が / または - というリテラルがある場合、その /C または /G オプションを使用する必要があります。おかげさまで ステファン のコメントで報告しています(現在は削除済み)。

検索文字列の長さ制限

Vistaでは、1つの検索文字列の最大許容長さは511バイトです。検索文字列が511を超える場合、その結果は FINDSTR: Search string too long. エラーが発生し、ERRORLEVELが2になります。

正規表現検索を行う場合、検索文字列の最大長は254です。長さが255から511の間の正規表現を使用すると FINDSTR: Out of memory 正規表現の長さが >511 の場合、ERRORLEVEL 2 のエラーが発生します。 FINDSTR: Search string too long. というエラーが発生します。

Windows XPでは、検索文字列の長さが短くなるようです。 Findstr error: "検索文字列が長すぎる": for"ループで部分文字列を抽出して一致させるには? XPでは、リテラル検索、正規表現検索ともに127バイトが上限となっています。

行長制限

コマンドライン引数または/F:FILEオプションで指定されたファイルには、行数の制限がないことが知られています。128MBのファイルに対して、1つの<LF>も含まない検索を実行することができました。

パイプラインデータおよびリダイレクト入力は、1行あたり8191バイトに制限されています。この制限はFINDSTRの機能です。この制限は、パイプやリダイレクトに固有のものではありません。リダイレクトされた標準入力やパイプで送られた入力を使ったFINDSTRは、>=8kバイトの行には決してマッチしません。8kバイトの行は標準エラーメッセージを生成しますが、少なくとも1つのファイルの少なくとも1つの行で検索文字列が見つかった場合、ERRORLEVELは0のままです。

検索のデフォルトのタイプ。リテラルと正規表現

/C:"string" - デフォルトは /L リテラルです。Lオプションと/C:"string"を明示的に組み合わせると確かに動作しますが、冗長です。

"string argument" - デフォルトは、一番最初の検索文字列の内容に依存する。 (検索文字列の区切りには <space> が使用されることを忘れないでください)。 最初の検索文字列が有効な正規表現で、エスケープされていないメタ文字を少なくとも1つ含む場合、すべての検索文字列は正規表現として扱われます。そうでなければ、すべての検索文字列はリテラルとして扱われます。例えば "51.4 200" は、最初の文字列がエスケープされていないドットを含むため、2つの正規表現として扱われるのに対し "200 51.4" は、最初の文字列にメタ文字が含まれていないため、2つのリテラルとして扱われます。

/G:file - デフォルトは、ファイル内の空でない最初の行の内容に依存する。最初の検索文字列が有効な正規表現で、エスケープされていないメタ文字を少なくとも1つ含んでいる場合、すべての検索文字列は正規表現として扱われます。そうでなければ、すべての検索文字列はリテラルとして扱われます。

推奨 - 常に明示的に指定する /L リテラルオプションまたは /R を使用する場合は、正規表現オプションを使用します。 "string argument" または /G:file .

BUG - 複数のリテラル検索文字列を指定すると、信頼性の低い結果になることがある。

次の単純なFINDSTRの例では、一致するものを見つけるべきなのに、失敗しています。

echo ffffaaa|findstr /l "ffffaaa faffaffddd"

この不具合は、Windows Server 2003、Windows XP、Vista、Windows 7で確認されています。

実験によると、以下の条件をすべて満たすとFINDSTRが失敗することがあります。

  • 複数のリテラル検索文字列を使用して検索している
  • 検索文字列の長さが異なる
  • 短い検索文字列は、長い検索文字列とある程度重複している
  • 大文字と小文字を区別して検索します。 /I オプション)

私が見たすべての失敗において、失敗するのはいつも短い検索文字列のうちの1つです。

詳しくは以下をご覧ください。 複数のリテラル検索文字列を使ったこのFINDSTRの例では、なぜ一致するものが見つからないのですか?

<ブロッククオート

コマンドライン引数内の引用符とバックスラッシュ

注意事項 ユーザーMC NDのコメントには、このセクションの実際の恐ろしく複雑なルールが反映されています。3つの解析フェーズがあります。

  • 最初のcmd.exeは、いくつかの引用符を^"としてエスケープする必要があるかもしれません(実際にはFINDSTRとは何の関係もありません)。
  • 次にFINDSTRは 2008年以前のMS C/C++の引数パーサー には特別なルールがあります。
  • 引数パーサーが終了した後、FINDSTRはさらに、♪の後に続く英数字はリテラルとして扱い、♪の後に続く英数字以外の文字はエスケープ文字として扱います。

このハイライト部分の残りは、100%正しいとは言えません。多くの場面でガイドとなり得ますが、完全に理解するには上記のルールが必要です。

コマンドライン検索文字列内の引用符のエスケープ

コマンドライン検索文字列内の引用符は、次のようにバックスラッシュでエスケープする必要があります。 \" . これは、リテラル検索文字列、正規表現検索文字列のいずれにも当てはまります。この は、XP、Vista、Windows 7で確認されています。

注: CMD.EXE パーサーのために引用符をエスケープする必要がある場合もありますが、これは FINDSTR とは関係ありません。たとえば を使用することができます。

FINDSTR \^" file && echo found || echo not found

コマンドラインリテラル検索文字列内のバックスラッシュのエスケープ

リテラル検索文字列のバックスラッシュは、通常、次のように表現されます。 \ または \\ . これらは通常、等価である。 (稀に Vistaでは、バックスラッシュを常にエスケープしなければならない場合がありますが、私はそのようなことはしません。 もはやテストするためのVistaマシンを持っていない) .

しかし、特殊なケースもあります。

連続したバックスラッシュを検索する場合、最後の である をエスケープします。最後のバックスラッシュはオプションでエスケープすることができる。

  • \\ は次のようにコード化することができます。 \\\ または \\\\
  • \\\ は次のようにコード化することができます。 \\\\\ または \\\\\\

引用符の前に1つ以上のバックスラッシュを検索すると、奇妙なことになります。論理的には ということは、引用符がエスケープされ、その後に続くそれぞれの バックスラッシュをエスケープする必要がありますが、これはうまくいきません! 代わりに 先頭のバックスラッシュはそれぞれ二重にエスケープしなければならず、引用符は は普通にエスケープされます。

  • \" は、次のようにコード化する必要があります。 \\\\\"
  • \\" は、次のようにコード化する必要があります。 \\\\\\\\\"

前述のように、1つまたは複数のエスケープされた引用符を使用する場合にも ^ CMD パーサーの場合

このセクションの情報は、XPとWindows 7で確認されています。

コマンドライン正規表現検索文字列内のバックスラッシュのエスケープ

  • Vistaのみ。 正規表現中のバックスラッシュは、以下のように二重にエスケープする必要があります。 \\\\ のように文字クラスセット内でシングルエスケープされます。 [\\]

  • XPとWindows 7。 正規表現におけるバックスラッシュは、常に次のように表現することができます。 [\\] . 通常、次のように表現されます。 \\ . しかし、これは決して は、バックスラッシュがエスケープされた引用符の前にある場合に動作します。

    エスケープされた引用符の前にある1つ以上のバックスラッシュは、以下のいずれかでなければなりません。 ダブルエスケープするか、あるいは [\\]

    • \" は、次のようにコード化されるかもしれません。 \\\\\" または [\\]\"
    • \\" は、次のようにコード化されるかもしれません。 \\\\\\\\\" または [\\][\\]\" または \\[\\]\"

G:FILEリテラル検索文字列内の引用符とバックスラッシュのエスケープ

G:fileで指定されたリテラル検索文字列ファイル内の独立した引用符とバックスラッシュはエスケープする必要はありませんが、エスケープすることは可能です。

"\" は等価である。

\\\ は等価である。

もし意図しているのが "find "であれば、少なくとも先頭のバックスラッシュはエスケープされなければならない。両方とも \\\\\\\ の作業を行います。

もし、"を見つけたいのであれば、少なくとも先頭のバックスラッシュはエスケープされなければなりません。どちらも \\"\\\" の作業を行います。

G:FILE正規表現検索文字列内の引用符とバックスラッシュのエスケープ

これは、エスケープシーケンスがドキュメントに基づく期待通りに機能する1つのケースです。引用符は正規表現のメタキャラクタではないので、エスケープする必要はありません(エスケープすることはできます)。バックスラッシュは正規表現のメタキャラクタであるため、エスケープする必要があります。

コマンドラインパラメータの文字数制限 - 拡張ASCII変換

ヌル文字(0x00)は、コマンドライン上のどの文字列にも出現させることはできません。その他の1バイト文字は、文字列(0x01〜0xFF)の中に出現させることができます。しかし、FINDSTR は、コマンドライン・パラメータ内で見つけた多くの拡張 ASCII 文字を他の文字に変換します。これは2つの点で大きな影響を及ぼします。

  1. 多くの拡張ASCII文字は、コマンドラインで検索文字列として使用された場合、それ自体がマッチしません。この制限は、リテラル検索と正規表現検索で同じです。検索文字列が拡張ASCIIを含む必要がある場合、検索文字列に /G:FILE オプションを代わりに使用する必要があります。

  2. FINDSTRは、ファイル名に拡張ASCII文字が含まれ、コマンドラインでファイル名が指定されている場合、ファイルの検索に失敗することがあります。検索するファイルの名前に拡張 ASCII が含まれている場合は /F:FILE オプションを使用する必要があります。

FINDSTRがコマンドライン文字列に対して実行する拡張ASCII文字変換の完全なリストは以下のとおりです。各文字は10進数のバイトコード値で表されています。最初のコードはコマンドラインで供給された文字を表し、2番目のコードはそれが変換された文字を表します。 注-このリストは米国のマシンで編集されたものです。他の言語がこのリストにどのような影響を与えるかはわかりません。

158 treated as 080     199 treated as 221     226 treated as 071
169 treated as 170     200 treated as 043     227 treated as 112
176 treated as 221     201 treated as 043     228 treated as 083
177 treated as 221     202 treated as 045     229 treated as 115
178 treated as 221     203 treated as 045     231 treated as 116
179 treated as 221     204 treated as 221     232 treated as 070
180 treated as 221     205 treated as 045     233 treated as 084
181 treated as 221     206 treated as 043     234 treated as 079
182 treated as 221     207 treated as 045     235 treated as 100
183 treated as 043     208 treated as 045     236 treated as 056
184 treated as 043     209 treated as 045     237 treated as 102
185 treated as 221     210 treated as 045     238 treated as 101
186 treated as 221     211 treated as 043     239 treated as 110
187 treated as 043     212 treated as 043     240 treated as 061
188 treated as 043     213 treated as 043     242 treated as 061
189 treated as 043     214 treated as 043     243 treated as 061
190 treated as 043     215 treated as 043     244 treated as 040
191 treated as 043     216 treated as 043     245 treated as 041
192 treated as 043     217 treated as 043     247 treated as 126
193 treated as 045     218 treated as 043     249 treated as 250
194 treated as 045     219 treated as 221     251 treated as 118
195 treated as 043     220 treated as 095     252 treated as 110
196 treated as 045     222 treated as 221     254 treated as 221
197 treated as 043     223 treated as 095
198 treated as 221     224 treated as 097

上記のリストにない文字 >0 は、それ自身として扱われます。 <CR> と< LF> . のような奇数文字を含めるのが最も簡単な方法です。 <CR><LF> は、環境変数に取得し、コマンドライン引数内で遅延展開を使用することです。

G:FILE、/F:FILEオプションで指定されたファイルに含まれる文字列の文字数制限について

nul (0x00) 文字はファイル内に出現することができますが、C言語の文字列終端記号のように機能します。nul文字以降の文字は、別の行にあるかのように別の文字列として扱われます。

<CR><LF> 文字は、文字列を終了させる行末文字として扱われ、文字列には含まれません。

その他の1バイト文字は、文字列内に完全に含まれます。

Unicodeファイルの検索

FINDSTR は、ほとんどの Unicode (UTF-16, UTF-16LE, UTF-16BE, UTF-32) を正しく検索できません。なぜなら、nul バイトを検索できず、Unicode には通常多くの nul バイトが含まれるからです。

しかし、TYPEコマンドは、BOM付きのUTF-16LEを1バイトの文字セットに変換するため、以下のようなコマンドは、BOM付きのUTF-16LEでも動作します。

type unicode.txt|findstr "search"

アクティブなコードページでサポートされていない Unicode コードポイントは、次のように変換されることに注意してください。 ? の文字が含まれています。

検索文字列がASCIIのみを含む限り、UTF-8の検索は可能です。ただし、マルチバイトのUTF-8文字が含まれる場合、コンソール出力は正しくありません。しかし、その出力をファイルにリダイレクトすれば、結果は正しくUTF-8にエンコードされたものになります。UTF-8ファイルがBOMを含んでいる場合、BOMは最初の行の一部とみなされ、行頭にマッチする検索を失敗させる可能性があることに注意してください。

UTF-8でエンコードされた検索ファイル(BOMなし)に検索文字列を入れ、/Gオプションを使用すると、マルチバイトのUTF-8文字を検索することが可能です。

行末

FINDSTRは、<LF>ごとに即座に改行します。CR>の有無は改行に影響を与えません。

改行をまたいで検索する

予想通り . 正規表現のメタキャラクタは <CR> および <LF> にマッチしません。しかし、コマンドライン検索文字列を使用して、改行をまたいで検索することは可能です。この場合、<CR> と <LF> の両方の文字を明示的にマッチングさせる必要があります。複数行のマッチが見つかった場合、マッチの1行目のみが出力されます。FINDSTRは、ソースの2行目まで戻って検索をやり直す、いわばquot;look ahead;タイプの機能です。

TEXT.TXTの内容が以下の通りだとします(Unix風でもWindows風でも構いません)。

A
A
A
B
A
A

次にこのスクリプト

@echo off
setlocal
::Define LF variable containing a linefeed (0x0A)
set LF=^


::Above 2 blank lines are critical - do not remove

::Define CR variable containing a carriage return (0x0D)
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"

setlocal enableDelayedExpansion
::regex "!CR!*!LF!" will match both Unix and Windows style End-Of-Line
findstr /n /r /c:"A!CR!*!LF!A" TEST.TXT

は次のような結果をもたらします。

1:A
2:A
5:A

G:FILEオプションによる改行をまたいだ検索は、<CR> や <LF> にマッチさせるには、EOL文字を挟んだ正規文字クラスの範囲表現しかないので、不正確です。

  • [<TAB>-<0x0B>] は <LF> にマッチしますが、 <TAB> と <0x0B> にもマッチします。

  • [<0x0C>-!] は <CR> にマッチしますが、 <0x0C> にもマッチしますし、 !

注 - 文字をグラフィカルに表現できないので、上記は正規表現のバイトストリームをシンボリックに表現したものです。

回答は以下のパート2に続きます...