はじめ
にこの回答の情報の多くは、Vistaマシンで実行された実験に基づいて収集されています。特に明記されていない限り、この情報が他のWindowsバージョンに適用されるかどうかは確認していません。
FINDSTR
の出力ドキュメントは、FINDSTRの出力をわざわざ説明することはありません。これは、一致する行が印刷されるという事実をほのめかしますが、それ以上のものはありません。
マッチングライン出力のフォーマットは次のとおりです。
filename:lineNumber:lineOffset:text
どこ
fileName: =一致する行を含むファイルの名前。要求が明示的に単一のファイルに対するものであった場合、またはパイプ入力またはリダイレクトされた入力を検索した場合、ファイル名は出力されません。印刷されると、fileNameには常に提供されたパス情報が含まれます。/S
オプションを使用すると、追加のパス情報が追加さ印刷されるパスは、常に指定されたパスを基準にします。指定されていない場合は、現在のディレクトリを基準にします。
注-非標準の(および十分に文書化されていない)ワイルドカード <
とを使用して複数のファイルを検索する場合は、ファイル名プレフィックスを回避できます>
。これらのワイルドカードがどのように機能するかについての正確なルールは、ここにあります。最後に、非標準のワイルドカードがFINDSTRでどのように機能するかを示すこの例を見ることができます。
lineNumber: = 10進値として表される一致する行の行番号で、1は入力の1行目を表します。/N
オプションが指定されている場合にのみ印刷さ
lineOffset: =一致する行の先頭の10進バイトオフセット。0は1行目の最初の文字を表します。/O
オプションが指定されている場合にのみ印刷さこれは、ライン内の一致のオフセットではありません。ファイルの先頭から行の先頭までのバイト数です。
text =任意の<CR>および/または<LF>を含む一致する行のバイナリ表現。バイナリ出力から何も残されていないため、すべての行に一致するこの例では、元のファイルの正確なバイナリコピーが生成されます。
FINDSTR "^" FILE >FILE_COPY
/ Aオプションは、fileName:、lineNumber:、およびlineOffset:出力のみの色を設定します。一致する行のテキストは、常に現在のコンソールの色で出力されます。/ Aオプションは、出力がコンソールに直接表示される場合にのみ有効です。/ Aオプションは、出力がファイルにリダイレクトされるか、パイプされる場合は効果がありません。出力がCONにリダイレクトされたときのバグのある動作の説明については、Aaciniの回答の2018-08-18編集を参照してください。
ほとんどの制御文字と多くの拡張ASCII文字は、XPではドットとして表示されます
。XPでは、FINDSTRは、一致する行からのほとんどの印刷不可能な制御文字をドット(ピリオド)として画面に表示します。次の制御文字は例外です。それらはそれ自体として表示されます:0x09タブ、0x0A LineFeed、0x0B垂直タブ、0x0Cフォームフィード、0x0Dキャリッジリターン。
XP FINDSTRは、拡張ASCII文字の数もドットに変換します。XPでドットとして表示される拡張ASCII文字は、コマンドラインで指定されたときに変換される文字と同じです。この投稿で後述する「コマンドラインパラメータの文字制限-拡張ASCII変換」セクションを参照してください。
制御文字と拡張ASCIIは、出力がパイプ処理されるか、ファイルにリダイレクトされるか、またはFOR IN()句内にある場合、XPではドットに変換されません。
VistaおよびWindows7は、常にすべての文字をドットとしてではなく、それ自体として表示します。
戻りコード(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
オプションを使用したファイル名。
リダイレクトによるstdinfindstr "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内のファイル名を引用符で囲まないようにする必要があります。名前が引用符で囲まれている場合、ファイルは見つかりません。
バグ-短い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
ただし、 and/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
正しく見つかります。
すべての短い名前がバグを引き起こすわけではありません。私が見たバグのある動作のすべてのインスタンスには、8.3の名前を必要としない通常の名前と同じように始まる短い8.3の名前を持つ3文字より長い拡張子が含まれます。
このバグは、XP、Vista、およびWindows7で確認されています。
印刷不可能な文字と/P
オプション
この/P
オプションにより、FINDSTRは、0〜7、14〜25、27〜31の10進バイトコードのいずれかを含むファイルをスキップします
。
言い換えると、この/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>
場合、FINDSTRは自動的<CR><LF>
に入力に追加します。これは、XP、Vista、およびWindows 7で確認されています(以前はWindowsパイプが入力の変更を担当していると思っていましたが、FINDSTRが実際に変更を行っていることがわかりました。)
Vistaのリダイレクトされた入力についても同じことが言えます。リダイレクトされた入力として使用されるファイルの最後の文字が、でない<LF>
場合、FINDSTRは自動的<CR><LF>
に入力に追加します。ただし、XPおよびWindows 7は、リダイレクトされた入力を変更しません。
リダイレクトされた入力がで終わらない場合、FINDSTRはXPおよびWindows7でハングします<LF>
これはXPおよびWindows7での厄介な「機能」です。リダイレクトされた入力として使用されるファイルの最後の文字がで終わらない<LF>
場合、FINDSTRは一度それが終わると無期限にハングしますリダイレクトされたファイルの最後に到達します。
パイプされたデータの最後の行が単一の文字で構成されている
場合、入力がパイプインされ、最後の行が後に続く単一の文字で構成されている<LF>
場合、FINDSTRは最後の行を完全に無視します。
例-1文字でnoの最初のコマンドは<LF>
一致しませんが、2文字の2番目のコマンドは正常に機能し、改行が終了する1文字の3番目のコマンドも正常に機能します。
> set /p "=x" <nul | findstr "^"
> set /p "=xx" <nul | findstr "^"
xx
> echo x| findstr "^"
x
DosTipsユーザーのSpongeBellyが新しいfindstrバグで報告しました。XP、Windows 7、およびWindows8で確認済み。Vistaについてはまだ聞いたことがありません。(テストするVistaはもうありません)。
オプションの構文
オプション文字は大文字と小文字を区別しないため/i
、/I
同等です。
オプションの前にいずれかを付けるか/
、-
オプションを単一/
またはの後に連結することができます-
。ただし、連結オプションリストには、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
or/G
オプションを使用する必要があります。コメントでこれを報告してくれたStephanに感謝します(削除されたため)。
検索文字列の長さの制限
Vistaでは、単一の検索文字列に許可される最大長は511バイトです。検索文字列が511を超えるFINDSTR: Search string too long.
と、ERRORLEVEL2のエラーが発生します。
正規表現検索を実行する場合、検索文字列の最大長は254です。255〜511の長さの正規表現ではFINDSTR: Out of memory
、ERRORLEVEL2のエラーが発生します。正規表現の長さが>511の場合、FINDSTR: Search string too long.
エラーが発生します。
Windows XPでは、検索文字列の長さが明らかに短くなっています。Findstrエラー:「検索文字列が長すぎます」:「for」ループで部分文字列を抽出して照合するにはどうすればよいですか?
XPの制限は、リテラル検索と正規表現検索の両方で127バイトです。
行の長さの制限
コマンドライン引数として、または/ F:FILEオプションを介して指定されたファイルには、既知の行の長さの制限はありません。<LF>が1つも含まれていない128MBのファイルに対して検索が正常に実行されました。
パイプされたデータとリダイレクトされた入力は、1行あたり8191バイトに制限されています。この制限は、FINDSTRの「機能」です。パイプやリダイレクトに固有のものではありません。リダイレクトされたstdinまたはパイプ入力を使用するFINDSTRは、8kバイトを超える行と一致することはありません。行>=8kは、stderrへのエラーメッセージを生成しますが、検索文字列が少なくとも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
バグ-複数のリテラル検索文字列を指定すると、信頼性の低い結果が得られる可能性があります
次の簡単なFINDSTRの例では、一致するはずなのに一致するものを見つけることができません。
echo ffffaaa|findstr /l "ffffaaa faffaffddd"
このバグは、Windows Server 2003、Windows XP、Vista、およびWindows7で確認されています。
実験に基づいて、次のすべての条件が満たされた場合、FINDSTRは失敗する可能性があります。
- 検索は複数のリテラル検索文字列を使用しています
- 検索文字列の長さが異なります
- 短い検索文字列は、長い検索文字列とある程度重複しています
- 検索では大文字と小文字が区別されます(
/I
オプションなし)
私が見たすべての失敗で、失敗するのは常に短い検索文字列の1つです。
詳細については、「複数のリテラル検索文字列を使用したこのFINDSTRの例で一致が見つからないのはなぜですか? 」を参照してください。
コマンドライン引数内の引用符とバックスラース注-ユーザー MCNDのコメントは、このセクションの実際の恐ろしく複雑なルールを反映しています。関連する3つの異なる解析フェーズがあります。
- 最初のcmd.exeでは、引用符を^ "としてエスケープする必要がある場合があります(実際にはFINDSTRとは関係ありません)。
- 次のFINDSTRは、2008年以前のMS C / C ++引数パーサーを使用します。これには、「」と「\」の特別なルールがあります。
- 引数パーサーが終了した後、FINDSTRはさらに、\の後に英数字をリテラルとして扱いますが、\の後に英数字以外の文字をエスケープ文字として扱います。
この強調表示されたセクションの残りの部分は100%正しくありません。多くの状況でガイドとして使用できますが、完全に理解するには上記のルールが必要です。
コマンドライン検索文字列内の引用符のエスケープコマンドライン検索文字列
内の引用符は、のように円記号でエスケープする必要があります
\"
。これは、リテラル検索文字列と正規表現検索文字列の両方に当てはまります。この情報は、XP、Vista、およびWindows7で確認されています。
注:CMD.EXEパーサーの引用符もエスケープする必要がある場合がありますが、これはFINDSTRとは関係ありません。たとえば、一重引用符を検索するには、次のように使用できます。
FINDSTR \^" file && echo found || echo not found
コマンドラインでのバックスラッシュのエスケープリテラル検索文字列リテラル検索文字列でのバックスラッシュは、通常、またはとして
表すことができます
。それらは通常同等です。(Vistaでは、バックスラッシュを常にエスケープする必要があるという珍しいケースがあるかもしれませんが、テストするVistaマシンがもうありません)。\
\\
ただし、いくつかの特殊なケースがあります。
連続する円記号を検索するときは、最後を除くすべてをエスケープする必要があります。最後の円記号はオプションでエスケープできます。
\\
\\\
またはとしてコーディングできます\\\\
\\\
\\\\\
またはとしてコーディングできます\\\\\\
引用の前に1つ以上の円記号を検索するのは奇妙です。ロジックは、引用符をエスケープする必要があり、先頭の円記号のそれぞれをエスケープする必要があることを示唆しますが、これは機能しません!代わりに、先頭の各円記号を二重にエスケープする必要があり、引用符は通常どおりエスケープされます。
\"
次のようにコーディングする必要があります\\\\\"
\\"
次のようにコーディングする必要があります\\\\\\\\\"
前述のように、1つ以上のエスケープされた引用符は^
、CMDパーサーのためにエスケープする必要がある場合もあります
このセクションの情報は、XPおよびWindows7で確認されています。
コマンドライン正規表現検索文字列内でのバックスラッシュのエスケープ
Vistaのみ:正規表現のバックスラッシュは、のよう\\\\
にダブルエスケープするか、のように文字クラスセット内でシングルエスケープする
必要があります。[\\]
XPおよびWindows7:正規表現のバックスラッシュは常にとして表すことができます[\\]
。通常はとして表すことができます\\
。ただし、バックスラッシュがエスケープされた引用符の前にある場合、これは機能しません。
エスケープされた引用符の前の1つ以上の円記号は、二重エスケープするか、次のようにコーディングする必要があります。[\\]
\"
\\\\\"
またはとしてコーディングできます[\\]\"
\\"
\\\\\\\\\"
またはとしてコーディングでき[\\][\\]\"
ます\\[\\]\"
/ G:FILEリテラル検索文字列
内の引用符と円記号のエスケープ/ G:fileで指定されたリテラル検索文字列ファイル内のスタンドアロンの引用符と円記号はエスケープする必要はありませんが、エスケープすることはできます。
"
と\"
は同等です。
\
と\\
は同等です。
\\を見つけることが目的の場合は、少なくとも先頭の円記号をエスケープする必要があります。\\\
と\\\\
仕事の両方。
「」を見つけることが目的の場合は、少なくとも先頭の円記号をエスケープする必要があります。両方とも\\"
機能し\\\"
ます。
/ G:FILE正規表現検索文字列内での引用符と円記号のエスケープ
これは、ドキュメントに基づいてエスケープシーケンスが期待どおりに機能する1つのケースです。引用符は正規表現のメタ文字ではないため、エスケープする必要はありません(ただし、エスケープすることはできます)。バックスラッシュは正規表現のメタ文字であるため、エスケープする必要があります。
コマンドラインパラメータの文字制限-拡張ASCII変換
ヌル文字(0x00)は、コマンドラインのどの文字列にも表示できません。その他の1バイト文字は、文字列(0x01〜0xFF)に含めることができます。ただし、FINDSTRは、コマンドラインパラメータ内で検出した多くの拡張ASCII文字を他の文字に変換します。これには、次の2つの点で大きな影響があります。
コマンドラインで検索文字列として使用すると、多くの拡張ASCII文字は一致しません。この制限は、リテラル検索と正規表現検索でも同じです。検索文字列に拡張ASCIIを含める必要がある場合は、/G:FILE
代わりにこのオプションを使用する必要があります。
名前に拡張ASCII文字が含まれていて、ファイル名がコマンドラインで指定されている場合、FINDSTRはファイルの検索に失敗する可能性があります。検索するファイルの名前に拡張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オプションで指定されたファイルにある文字列の文字制限
ヌル(0x00)文字はファイルに表示できますが、C文字列ターミネータのように機能します。ヌル文字の後の文字は、別の行にあるかのように別の文字列として扱われます。
および文字は<CR>
、<LF>
文字列を終了する行末記号として扱われ、文字列には含まれません。
他のすべてのシングルバイト文字は、文字列内に完全に含まれます。
Unicodeファイル
の検索FINDSTRはnulバイトを検索できず、Unicodeには通常多くのnulバイトが含まれているため、ほとんどのUnicode(UTF-16、UTF-16LE、UTF-16BE、UTF-32)を適切に検索できません。
ただし、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行目に戻り、検索を最初からやり直します。これは、一種の「先読み」タイプの機能です。
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文字を挟む正規表現文字クラス範囲式を使用するためです。
注-文字をグラフィカルに表現できないため、上記は正規表現バイトストリームの記号表現です。
回答は以下のパート2に続きます...