亀の甲羅2

今日もまた朝とく起きて励まなん窓に明るきありあけの月

powershell におけるCSVの扱い方(1)<編集途中>

powershellCSVファイルを操作してみよう

CSVを編集しなければいけない機会があったので、powershellCSVをどのように扱うかを調べてみた。
もちろん基本的なことだけ。

目次

本文

1. CSVファイルの読み込み

基本的なCSVファイルの読み込み方

$CSV1 = Import-Csv ".\A.csv"

時々、SJISCSVもある。そういうときはEncoding指定する。

$CSV1 = Import-Csv ".\A.csv" -Encoding Default

2. 読み込まれたデータ

a

3. データの一部を編集する

a

4. CSVファイルとして出力する

# objをCSVに変換
$csv = obj |ConvertTo-Csv -NoTypeInformation
# CSVをファイルに出力
$csv  | Out-File "C.csv"

上記ではBOM付きのUTF-8になってしまうので、Encoding指定してみた。

$csv | Out-File $outfile -Encoding UTF8

うーーん。どうやってもBOM付きUTF-8にしかならなかった。
代替案として、以下のようにするといいみたい。

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
[System.IO.File]::WriteAllLines($outfile, $csv, $Utf8NoBomEncoding)

# $outfile : 出力ファイル名
# $csv : CSVデータ

SJIS形式のCSVで出力したい場合には、下記の通り。

# objをCSVに変換
$csv = obj |ConvertTo-Csv -NoTypeInformation
# CSVをファイルに出力
$csv  | Out-File "C.csv" -Encoding Default

5. 列名(プロパティ名)を除いてデータ部だけを出力するTips

Select -Skip 1 で1行目(列名)をSkipしてファイル出力している。

$obj | ConvertTo-Csv -NoTypeInformation | Select -Skip 1 | Out-File "C.csv"

6. 列名(プロパティ名)だけを取得する方法

CSVの1行目にある列名だけを取得する方法。

> $CSV2 = Import-Csv ".\B.csv"
> $CSV2 | Get-member -MemberType 'NoteProperty' | Select-Object -ExpandProperty 'Name'
NO
STRING
UTIL

7. 2つのCSVファイルを横結合(結合条件は用いずただの左結合)

結合するにあたり主キーが一致していることを確認せずに単純に左結合する。

$left_csv_filename = "A.csv"
$right_csv_filename = "B.csv"
$out_csv_filename = "C.csv"

# CSVファイルはカレントフォルダを前提とする
$FilePATH = JOIN-PATH $PSScriptRoot $left_csv_filename
$leftcsv = Import-Csv $FilePATH
$FilePATH = JOIN-PATH $PSScriptRoot $right_csv_filename
$rightcsv = Import-Csv $FilePATH

# 右CSVファイルの列名(プロパティ名)だけを取得
$pp = $rightcsv | Get-member -MemberType 'NoteProperty' | Select-Object -ExpandProperty 'Name'

$pp | %{

    $prop = $_
    # 列$propのデータを左CSVにJOIN
    $leftcsv = joincsv $leftcsv $rightcsv $prop

    # 右CSVの列数分行う
}

# output
$outfile = JOIN-PATH $PSScriptRoot $out_csv_filename
$csv = $leftcsv | ConvertTo-Csv -NoTypeInformation
#$csv | Out-File $outfile -Encoding UTF8
# この方法でもCSV作成できるがBOMありのUTF-8になってしまう。BOM無しの指定が不明のため、暫時下記の通り対応する。

$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
[System.IO.File]::WriteAllLines($outfile, $csv, $Utf8NoBomEncoding)


#-----------------------------------------------------------------------
# 左CSVファイルに指定のプロパティ列の情報を結合する
# $obj_csv : left csv file
# $obj_csv2 : right csv file
# $obj_csv : property name on right csv file
#
# note : 左CSVと右CSVで同じ列名は許可しません(エラーになります)
#
function joincsv($obj_csv, $obj_csv2, $prop){

    $obj_csv | % -Begin {$row = 0} {
         $_ | Add-Member -MemberType NoteProperty -Name $prop -Value $obj_csv2[$row].$prop -PassThru
        $row++
    }

    return
}

8. 2つのCSVファイルを左結合(結合条件を用いたLEFT INNER JOIN/LEFT OUTER JOIN)

a

   


バージョン情報

> $PSVersionTable

Name                           Value                                                                                                          
----                           -----                                                                                                          
PSVersion                      5.1.19041.1023