[PowerShell] csv 読み込み,行数で型が違った件
まず,はじめに動作環境は Windows Server2008 R2です.
$PSVersionTable は下記.
#Powershell 初心者です.自分備忘録なので,正しいとは限りません.そこのとこよろしくお願いいたします
Name Value ---- ----- CLRVersion 2.0.50727.5485 BuildVersion 6.1.7601.17514 PSVersion 2.0 WSManStackVersion 2.0 PSCompatibleVersions {1.0, 2.0} SerializationVersion 1.1.0.1 PSRemotingProtocolVersion 2.1
タイトルどおりの件なのですが,自分が引っかかってなかなか気づかなかったので備忘録として.
結論からいうと,1行なのか,複数行かによって各要素へのアクセス方法が違った感じです.
やりたいこと
{,} 区切りの csv を読み込んで,一行ずつ処理をすること.
PSv3 なら,{Import-Csv} を使えば, encoding も一緒にかけて,幸せ.
Import-Csv -Encoding Default $listName
ただ,今回はPSv2での読み込みなので,Import-CSVはちょっと置いておきますね.
データは,こんな感じに用意します.
サンプルデータ:sample_3.csv
name,sex,age emily,f,16 nancy,f,20 hamada,m,50
とりあえず,読み込み・
Get-Content $listName_3 | ConvertFrom-Csv
結果表示.
name sex age ---- --- --- emily f 16 nancy f 20 hamada m 50
そうそう,ちゃんと読み取れてますね.
各要素にアクセスしたいときは,こんな感じ.
$line = Get-Content $listName_3 | ConvertFrom-Csv for ( $i=0; $i -lt $line.Length ;$i++) { Write-Host "name-> "$line[$i].name" sex-> "$line[$i].sex" age-> "$line[$i].age }
結果.
name-> emily sex-> f age-> 16 name-> nancy sex-> f age-> 20 name-> hamada sex-> m age-> 50
と,ここまでは順調なんですね.
私がハマったのは,データが1行分しかないときです.
サンプルデータ:sample_1.csv
name,sex,age emily,f,16
同様に,読み込みます.
Get-Content $listName_1 | ConvertFrom-Csv
もちろん,ちゃんと読み取れてます.私には,先ほどとかわりがわからない…
name sex age ---- --- --- emily f 16
私の中では,$line.length は 1 になり, $line[0].name のようにアクセスできるものだと思っていました.まぁ,やってみると,怒られます.
型 System.Management.Automation.PSObject のオブジェクトにインデックスを付けることはできません。
どういうことなの?と思って,型を調べてみると↓
$line = Get-Content $listName_1 | ConvertFrom-Csv $line.GetType()
IsPublic IsSerial Name BaseType -------- -------- ---- -------- True False PSCustomObject System.Object
PSCustomObject?たしかに,エラーメッセージにも書いてある….
え,じゃあ複数行の時は??
IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object[] System.Array
Array とか書いてある,たしかに複数行っぽく認識してる….
ということで,1行のときは配列として認識しないようです.
アクセスするときは,
$line.name , $line.sex, $line.age
みたいにしてあげるべきみたいですね.
CSVを読み込んで,別のコマンドに渡す,というようなスクリプトを書いていたのでテストデータを1行にすると
ずっと処理が正しく進まないので,不思議に思ってたらこういうことでした.
Get-content で Convert するときは,1行か複数行かちゃんと判別しないとダメなのかな.
Import-Csv もそのうち,調べてみます.