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