個人の備忘です。毎回調べなおすのツラいので。
やりたいこと
Import-CSV
等でファイルを読み込んだあとのPSCustomObjectの列名(NoteProperty)はRead-Onlyだが、Write-SQLTableData
に渡す時にデータベーステーブルの列名と合わせる必要がありなんとかして列名を変えたい。オブジェクトのコピーはメモリを圧迫するのでしたくない。
実現方法
いろいろ試したが、Select-Object
で集計プロパティ***(@{Name=Foo;Expression={$_.Bar}})***を活用して出力し、オブジェクト上書きするのが一番楽。だがスクリプトブロックを文字列にしてInvoke-Expression
する必要がある。(私がヘボいだけで他に方法があるのかもしれない)
sample.ps1
# CSV読み込み
$temp = Get-Content $file -encoding UTF8 | ConvertFrom-CSV
# 現在のプロパティ名をリストする
$null = ( $temp | get-member -force | Where-Object{ $_.name -eq "psextended" } | ForEach-Object { $_.definition } ) -match "psextended {(.+)}"
$cols = $matches[1] -split ", "
$newcols = @("a","b","c") #新しい列名
# 新しいカラム順に内容を並べ替えて$tempを書き換える
$cnt = 0
$buff = "`$temp = `$temp | Select-Object "
foreach($col in $newcols) {
if ($cnt -ne 0) { $buff = $buff + ","}
$buff = $buff + " @{Name='$($headers[$cnt])';Expression={`$_.`"$col`"}}"
$cnt++
}
$buff = $buff + ""
Invoke-Expression $buff
愚痴
PSCustomObjectは優秀なんだけど、DataFrame的に使うのは難しい。
Write-SQLTableData()にはSystem.Data.DataTableも渡せるよう(*リンク)なので、今後はDataTableに読み込ませるようにしようかな。。。