序文
この回答の情報の多くは、Vistaマシンで実行された実験に基づいて収集されたものです。特に明記されていない限り、この情報が他のバージョンのWindowsに適用されるかどうかは確認していません。
FINDSTRの出力
ドキュメントでは、FINDSTRの出力について説明することはありません。これは、一致する行が印刷されることをほのめかしていますが、それ以上のものはありません。
一致する行の出力の形式は次のとおりです。
filename:lineNumber:lineOffset:text
どこ
fileName: =一致する行を含むファイルの名前。要求が明示的に単一のファイルに対するものである場合、またはパイプ入力またはリダイレクト入力を検索する場合、ファイル名は出力されません。印刷すると、fileNameには常に、提供されたパス情報が含まれます。/S
オプションを使用すると、追加のパス情報が追加されます。表示されるパスは、常に指定されたパスに相対的です。指定されていない場合は、現在のディレクトリに相対的です。
注-複数のファイルを検索する場合、非標準の(文書化が不十分な)ワイルドカード <
とを使用して、ファイル名の接頭辞を回避できます>
。これらのワイルドカードがどのように機能するかについての正確なルールは、こちらにあります。最後に、非標準のワイルドカードがFINDSTRでどのように機能するかの例を見ることができます。
lineNumber: = 10進数として表される一致する行の行番号。1は入力の最初の行を表します。/N
オプションが指定されている場合にのみ出力されます。
lineOffset: =一致する行の先頭の10進バイトオフセット。0は最初の行の最初の文字を表します。/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と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は、次のソースの1つからのみデータを検索できます。
引数として、または/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 内のファイル名を引用符で囲まないでください。名前が引用されている場合、ファイルは見つかりません。
バグ/D
/S
-8.3 ファイル名が短いと、オプションが壊れる可能性がありますすべての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
適切に見つかります。
すべての短い名前がバグの原因になるわけではありません。私が見たバグのある動作のすべてのインスタンスには、8.3文字の名前を必要としない通常の名前と同じように始まる、短い8.3文字の名前を持つ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>
挿入され、ストリームの最後の文字がでない場合、FINDSTRは自動的<CR><LF>
に入力に追加します。これは、XP、Vista、およびWindows 7で確認されています(以前は、Windowsパイプが入力の変更に責任があると思っていましたが、FINDSTRが実際に変更を行っていることを発見しました。)
Vistaでリダイレクトされた入力についても同様です。リダイレクトされた入力として使用されるファイルの最後の文字がでない<LF>
場合、FINDSTRは自動的<CR><LF>
に入力に追加します。ただし、XPおよびWindows 7はリダイレクトされた入力を変更しません。
リダイレクトされた入力がで終了しない場合、FINDSTRがXPおよびWindows 7でハングする<LF>
これは、XPおよびWindows 7で厄介な「機能」です。リダイレクトされた入力として使用されるファイルの最後の文字がで終了しない<LF>
場合、FINDSTRは一度無限にハングします。リダイレクトされたファイルの終わりに達します。
それは単一の文字で構成されている場合はパイプによるデータの最後の行は無視することができる
入力が中にパイプされ、最後の行が続いていない単一の文字で構成されている場合<LF>
は、FINDSTR完全に最後の行を無視します。
例<LF>
-1 文字で最初のコマンドは一致しませんが、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はもうありません)。
オプションの構文
オプションの前にどちらかを付けるか/
、-
オプションを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"
検索文字列の長さの制限
Vistaでは、単一の検索文字列に許可される最大長は511バイトです。検索文字列が511を超える場合、結果はFINDSTR: Search string too long.
ERRORLEVEL 2のエラーになります。
正規表現検索を実行する場合、検索文字列の最大長は254です。255から511までの長さの正規表現はFINDSTR: Out of memory
、ERRORLEVEL 2のFINDSTR: Search string too long.
エラーになります。正規表現の長さが> 511の場合、エラーが発生します。
Windows XPでは、検索文字列の長さが明らかに短いです。Findstrエラー:「検索文字列が長すぎます」:「for」ループで部分文字列を抽出して照合する方法
XP制限は、リテラル検索と正規表現検索の両方で127バイトです。
行の長さの制限
コマンドライン引数として、または/ F:FILEオプションを介して指定されたファイルには、既知の行の長さの制限はありません。検索は、単一の<LF>を含まない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
。
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で指定されたリテラル検索文字列ファイル内のスタンドアロンの引用符とバックスラッシュはエスケープする必要はありませんが、エスケープすることはできます。
"
と\"
同等です。
\
と\\
同等です。
\\を検索する場合は、少なくとも先頭のバックスラッシュをエスケープする必要があります。両方\\\
と\\\\
仕事。
目的は「\見つけることであれば、少なくとも主要なバックスラッシュをエスケープする必要があります。両方\\"
と\\\"
仕事。
/ G:FILE正規表現検索文字列内での引用符とバックスラッシュのエスケープ
これは、ドキュメントに基づいてエスケープシーケンスが期待どおりに機能する1つのケースです。引用は正規表現のメタ文字ではないため、エスケープする必要はありません(エスケープすることはできます)。バックスラッシュは正規表現のメタ文字であるため、エスケープする必要があります。
コマンドラインパラメータの文字制限-拡張ASCII変換
コマンドラインの文字列にnull文字(0x00)を使用することはできません。他の任意の1バイト文字を文字列に含めることができます(0x01-0xFF)。ただし、FINDSTRは、コマンドラインパラメータ内にある多くの拡張ASCII文字を他の文字に変換します。これは、次の2つの点で大きな影響を与えます。
1)コマンドラインで検索文字列として使用した場合、多くの拡張ASCII文字は一致しません。この制限は、リテラル検索と正規表現検索の場合と同じです。検索文字列に拡張ASCIIを含める必要がある場合は、/G:FILE
代わりにオプションを使用する必要があります。
2)名前に拡張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オプションで指定されたファイルにある文字列の文字制限
nul(0x00)文字はファイルに表示できますが、C文字列ターミネーターのように機能します。nul文字の後の文字は、別の行にあるかのように別の文字列として扱われます。
<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>の両方の文字を明示的に一致させる必要があります。複数行の一致が見つかった場合、一致の最初の行のみが印刷されます。次に、FINDSTRは、ソースの2行目に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文字を挟む正規表現文字クラス範囲式を使用するためです。
[<TAB>-<0x0B>]
<LF>に一致しますが、<TAB>および<0x0B>にも一致します
[<0x0C>-!]
<CR>に一致しますが、<0x0C>および!にも一致します。
注-文字をグラフィカルに表現できないため、上記は正規表現のバイトストリームのシンボリック表現です。
回答は以下のパート2に続きます...
grep
ているインストール/使用することもできます:-) たとえば、stackoverflow.com / questions / 2635740 /…を参照してください。