7

Powershell では、(キャリッジ リターン + 改行) を行末Select-Stringと見なすことを期待します。\r\n

ただし、以下に示すように、abc入力全体に一致します。

PS C:\Tools\hashcat> "abc`r`ndef" | Select-String -Pattern "abc"

abc
def

文字列を 2 つの部分に分割すると、Select-String期待どおりに動作します。

PS C:\Tools\hashcat> "abc", "def" | Select-String -Pattern "abc"

abc

Select-String行が で終わる文字列を指定し\r\n、このコマンドレットが一致を含む文字列のみを返すようにするにはどうすればよいですか?

4

3 に答える 3

7
  • Select-Stringは、(オンデマンドで文字列化された[1] )入力オブジェクトごとに動作します。

  • のような複数行の文字列"abc`r`ndef"は、単一の入力オブジェクトです。

    • 対照的に、は 2 つの入力オブジェクトとして渡される2"abc", "def"つの要素を持つ文字列配列です。
  • 複数行の文字列の行が個別に渡されるようにするには、 PowerShell の演算子を使用して文字列を行の配列に分割します。-split"abc`r`ndef" -split "`r?`n"

    • (これ?により、-only (LF のみ、Unix スタイル) の行末`rも正しく処理できるようになります。)`n

要するに:

"abc`r`ndef" -split "`r?`n" | Select-String -Pattern "abc"

PowerShell 文字列リテラルを正規表現 (regex) エスケープ シーケンス (の右辺は​​正規表現) で使用した場合と同等です-split

"abc`r`ndef" -split '\r?\n' | Select-String -Pattern "abc"

操作の実際の単位が入力オブジェクトであることを考えると、ドキュメンテーションがテキストSelect-Stringでの操作について述べているのは少し残念です。おそらく、これは、テキスト ファイルの行を 1 行ずつ出力するコマンドレットを介して入力オブジェクトを提供する典型的なユース ケースに 由来します。
Get-Content

一致する文字列を直接Select-String返すのではなく、一致に関する有用なメタデータを含むオブジェクトにラップすることに注意してください。ただし、一致する文字列を含むのはプロパティであるため、そこにも線のメタファーが存在します。[Microsoft.PowerShell.Commands.MatchInfo].Line


[1] オプションの読み方:Select-String入力オブジェクトを文字列化する方法

入力オブジェクトがまだ文字列でない場合は、文字列に変換されますが、期待どおりではない可能性があります。

大まかに言えば、.ToString()メソッドは文字列以外の入力オブジェクト[2]ごとに呼び出されます 。これは、文字列以外の場合、PowerShell の既定の出力書式設定で得られる表現と同じではありません(後者は、オブジェクトを出力するときに表示されるものです)。コンソールまたは使用、Out-Fileたとえば); 対照的に、これは、二重引用符で囲まれた文字列内の文字列補間で得られるのと同じ表現です(変数参照またはコマンドを"..."、たとえば"$HOME"またはに埋め込む場合"$(Get-Date)")。

多くの場合、インスタンス固有の情報を含まず.ToString()に、オブジェクトのtypeの名前を生成するだけです。たとえば、 に$PSVersionTable文字列化しSystem.Management.Automation.PSVersionHashTableます。

# Matches NOTHING, because Select-String sees
# 'System.Management.Automation.PSVersionHashTable' as its input.
$PSVersionTable | Select-String PSVersion 

デフォルトの出力形式を行ごとに検索たい場合は、次のイディオムを使用します。

... | Out-String -Stream | Select-String ...

ただし、文字列以外の入力の場合は条件を使用してプロパティをクエリして入力をフィルター処理する方が堅牢であり、後続の処理に適していることに注意してください。Where-Object

とは言うものの、この GitHub 機能リクエストで説明されているように、暗黙的に文字列化を適用する必要があるという強力なケースがありSelect-StringOut-String -Streamます。


[2] より正確に.psobject.ToString()は、そのまま、またはオブジェクトのToStringメソッドが型指定されたIFormatProvider引数をサポートしている場合は、カルチャに不変な表現.psobject.ToString([cultureinfo]::InvariantCulture)を取得するために呼び出されます。詳細については、この回答を参照してください。

于 2018-04-22T23:10:42.297 に答える