PowerShellスクリプトで、Format-Table
CmdLetに渡すオブジェクトがいくつかあります。
私のスクリプトの出力は次のようになります:
Something...
Operation AttributeName AttributeValue
--------- ------------- --------------
Delete Member John Doe
Something else...
フィールドの意味は一目瞭然なので、Format-Tableの出力からヘッダー、 '---'セパレーター、最初と最後の空白行を削除したいと思います。
CmdLetがこれをサポートしているとは思いません(または、少なくともこれを行うためのパラメーターがある場合、それを見つけることができませんでした)。
Format-Tableの出力からの実際の値を含む行のみを残すための最良の方法は何ですか?
-HideTableHeaders
パラメータをFormat-Table
に試します。
gci | ft -HideTableHeaders
(私はPowerShell v2を使用しています。これがv1にあったかどうかはわかりません。)
-ExpandProperty
をお試しください。たとえば、クリーンな変数をOut-Gridview -PassThru
に送信するためにこれを使用します。それ以外の場合、変数にはヘッダー情報が格納されています。複数のプロパティを返す場合は、これらは適切ではないことに注意してください。
例:
Get-ADUser -filter * | select name -expandproperty name
または、次のようにすることもできます。
(Get-ADUser -filter * ).name
-HideTableHeaders
パラメータを指定しても、残念ながらまだ空の行が出力されます(そして、表のヘッダーは列の幅と見なされます)。ここで確実に機能することがわかっている唯一の方法は、出力を自分でフォーマットすることです。
| % { '{0,10} {1,20} {2,20}' -f $_.Operation,$_.AttributeName,$_.AttributeValue }
これが私がこれを解決する方法です。出力をパイプでOut-Stringに渡し、その出力を.NET Trim関数に渡します。
(gci | ft -HideTableHeaders | Out-String).Trim()
これにより、テーブルの前後の改行が削除されます。
末尾の改行が必要な場合は、TrimStartを使用してヘッダーの改行を処理することもできます。
(gci | ft -HideTableHeaders | Out-String).TrimStart()
別のアプローチは、 ForEach-Object を使用して個々のアイテムを文字列に投影し、次に Out-String CmdLetを使用して最終結果を文字列または文字列配列に投影することです。
gci Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT\CID | foreach { "CID Key {0}" -f $_.Name } | Out-String
#Result: One multi-line string equal to:
@"
CID Key HKEY_CLASSES_ROOT\CID\2a621c8a-7d4b-4d7b-ad60-a957fd70b0d0
CID Key HKEY_CLASSES_ROOT\CID\2ec6f5b2-8cdc-461e-9157-ffa84c11ba7d
CID Key HKEY_CLASSES_ROOT\CID\5da2ceaf-bc35-46e0-aabd-bd826023359b
CID Key HKEY_CLASSES_ROOT\CID\d13ad82e-d4fb-495f-9b78-01d2946e6426
"@
gci Microsoft.PowerShell.Core\Registry::HKEY_CLASSES_ROOT\CID | foreach { "CID Key {0}" -f $_.Name } | Out-String -Stream
#Result: An array of single line strings equal to:
@(
"CID Key HKEY_CLASSES_ROOT\CID\2a621c8a-7d4b-4d7b-ad60-a957fd70b0d0",
"CID Key HKEY_CLASSES_ROOT\CID\2ec6f5b2-8cdc-461e-9157-ffa84c11ba7d",
"CID Key HKEY_CLASSES_ROOT\CID\5da2ceaf-bc35-46e0-aabd-bd826023359b",
"CID Key HKEY_CLASSES_ROOT\CID\d13ad82e-d4fb-495f-9b78-01d2946e6426")
このアプローチの利点は、結果を変数に格納でき、空の行がないことです。
私はそれが2年遅れていることを知っていますが、これらの答えは、オブジェクトを出力して結果の文字列をトリミングするフィルター関数を定式化するのに役立ちました。最終的なソリューションではすべてを文字列にフォーマットする必要があるので、少し異なる方法で取り組みました。長い間、私の問題は非常によく似ており、このように見えます
$verbosepreference="Continue"
write-verbose (ls | ft | out-string) # this generated too many blank lines
これが私の例です:
ls | Out-Verbose # out-verbose formats the (pipelined) object(s) and then trims blanks
私のOut-Verbose関数は次のようになります。
filter Out-Verbose{
Param([parameter(valuefrompipeline=$true)][PSObject[]]$InputObject,
[scriptblock]$script={write-verbose "$_"})
Begin {
$val=@()
}
Process {
$val += $inputobject
}
End {
$val | ft -autosize -wrap|out-string |%{$_.split("`r`n")} |?{$_.length} |%{$script.Invoke()}
}
}
注1:このソリューションは、数百万のオブジェクトのように拡張されません(パイプラインをシリアルに処理しません)。
注2:-noheaddingsオプションを追加することもできます。ここでスクリプトブロックを使用した理由を不思議に思っている場合は、ディスクファイルやその他の出力ストリームに送信するようなオーバーロードを許可するためです。