web-dev-qa-db-ja.com

Findstr-正規表現の一致のみを返します

この文字列はテキストファイル(test.txt)にあります:

BLA BLA BLA
BLA BLA
Found 11 errors and 7 warnings

私はこのコマンドを実行します:

findstr /r "[0-9]+ errors" test.txt

11 errors文字列だけを取得するため。

代わりに、出力は次のとおりです。

Found 11 errors and 7 warnings

誰かが助けることができますか?

6
ohadinho

findstrツールは、一致のみを抽出するために使用することはできません。これにはPowershellを使用する方がはるかに簡単です。

次に例を示します。

$input_path = 'c:\ps\in.txt'
$output_file = 'c:\ps\out.txt'
$regex = '[0-9]+ errors'
select-string -Path $input_path -Pattern $regex -AllMatches | % { $_.Matches } | % { $_.Value } > $output_file

上記のスクリプトの使用方法については、 Windows PowerShell:正規表現を使用した文字列の抽出の記事 を参照してください。

4

findstrは常に、一致を含むすべての全行を返します。サブ文字列のみを返すことはできません。したがって、自分で部分文字列の抽出を行う必要があります。とにかく、findstrコマンドラインにいくつかの問題があります。これを指摘しておきます。

findstrの文字列パラメータは実際には空白で区切られた複数の検索文字列を定義するため、1つの検索文字列は[0-9]+で、もう1つはerrorです。テキストファイルの行Found 11 errors and 7 warningsは、Word errorのみが原因で返されます。また、findstr+文字(1つ以上のオカレンス)をサポートしていないため、数値部分は一致の一部ではありません。前の文字またはクラス)、それを実現するには、検索文字列のその部分を[0-9][0-9]*に変更する必要があります。文字列全体を1つの検索文字列として扱うには、/Cオプションを指定する必要があります。これはデフォルトでリテラル検索モードになっているため、さらに/Rオプションを明示的に追加する必要があります。

findstr /R /C:"[0-9][0-9]* errors" "test.txt"

ただし、これをすべて変更すると、x5 errorseのような文字列にも一致します。 \<(Wordの始まり)や\>(Wordの終わり)のようなWordの境界を使用できないようにするためです。 (または、検索文字列の両側にスペースを含めることもできるため、/C:" [0-9][0-9]* errors "ですが、検索文字列が該当する行の最初または最後に表示されると、問題が発生する可能性があります。)

したがって、上記のすべてに関して、修正および改善されたコマンドラインは次のようになります。

findstr /R /C:"\<[0-9][0-9]* errors\>" "test.txt"

これにより、一致を含む行全体が返されます。

Found 11 errors and 7 warnings

そのような行のみを返し、2 errors are enough35 warnings but less than 3 errorsのような行を除外したい場合は、もちろん、それに応じて検索文字列を拡張できます。

findstr /R /C:"^Found [0-9][0-9]* errors and [0-9][0-9]* warnings$" "test.txt"

とにかく、部分11 errorsを抽出するには、いくつかのオプションがあります。

  1. for /Fループは、findstrの出力を解析し、特定のトークンを抽出できます。

    for /F "tokens=2-3 delims= " %%E in ('
        findstr/R /C:"\<[0-9][0-9]* errors\>" "test.txt"
    ') do echo(%%E %%F
    
  2. 部分文字列置換構文も使用できます。

    for /F "delims=" %%L in ('
        findstr /R /C:"\<[0-9][0-9]* errors\>" "test.txt"
    ') do set "LINE=%%L"
    set "LINE=%LINE:* =%"
    set "LINE=%LINE: and =" & rem "%"
    echo(%LINE%
    
5
aschipfl