#【PowerShell】Csvファイルを指定行数ごとに分割してExportする
初めての投稿です
忘れないようにメモ程度に、、、
##行数の多いCSVを分割したい
研究などで大きなデータをを扱うことがあり、csvファイルを分割して複数の端末に処理させたい。
以下のファイルを分割させたい。
性別,数字,URL
女,8363,http://test.net
男,2471,http://example.co.jp
男,7325,http://test.net
女,7682,http://example.co.jp
男,1005,http://sample.com
男,5318,http://test.org
男,3636,http://example.jp
男,6869,http://test.jp
女,7139,http://sample.co.jp
男,9930,http://test.jp
女,2933,http://example.co.jp
男,892,http://test.jp
男,8262,http://sample.com
女,6455,http://test.jp
男,4707,http://sample.co.jp
男,5199,http://example.org
女,251,http://test.com
女,5001,http://example.co.jp
男,7719,http://test.org
女,582,http://test.net
男,3598,http://example.co.jp
女,8149,http://sample.com
男,9911,http://example.net
女,5329,http://test.net
女,3368,http://test.net
女,38,http://example.jp
男,1927,http://example.jp
男,3636,http://sample.com
女,4759,http://test.com
女,3441,http://example.net
ファイルを分割するために以下の記事を参考にしてみた。
$i=0; Get-Content Sample.csv -Encoding UTF8 -ReadCount 3 | % {$_ | Out-File "sub_$i.csv" -Encoding UTF8 -Append; $i++}
こちらは Get-Contentでcsvを読み込んでおり、-ReadCount オプションで何行ごとに処理をするのかを指定している。パイプで繋げ% (ForEach-Object)でOut-Fileで出力をしている。
3行処理するごとに$iに1足して書き出すファイル名を変えている。
1行目から3行目まではsub_0.csv
に書き込まれ、
次に4行目から6行目まではsub_1.csv
に書き込まれていきます。
こういったようにある行数で切って出力することができます。
しかしこのやり方では少し困ったことが出てくる。
##sub_1.csv以降のファイルにはヘッダーが付かない!!!
男,7325,http://test.net
女,7682,http://example.co.jp
男,1005,http://sample.com
sub_1.csv
以降のファイルにヘッダーが付かないため、ヘッダーが必要な際にヘッダーをつける必要がある。
また、Importしてヘッダーを無理やりつける方法もあるがスマートではない。
##ヘッダーもつけて出力させる方法
先にやり方を書くと以下になる。
#ファイルパス
$Path = "./Sample.csv"
#3行ずつ処理させるための数字
$div = 3
#csv読み込み
$csv = Import-Csv $Path -Encoding UTF8
#csvの行数カウント
$count_rows = Get-Content Sample.csv | Measure-Object
#出力されるファイル数分ループ
for($i=0;$i -lt $count_rows.Count/$div;$i++){
#開始位置
$a = $i*$div
#終了位置
$b = $i*$div+$div-1
#指定の行数範囲をファイルへ出力
$csv[$a..$b] | Export-Csv -NoTypeInformation "./Divided/Data${i}.csv" -Encoding UTF8
}
この出力方法だと配列に入っているcsvが呼ばれるため出力する際にはヘッダーが付与されて出力される。
今回は3行ごとにファイルを分けて出力するするため元のSample.csv
の行数($count_rows.Count
)から3で割ることによって必要な出力ファイルの数が分かる。
必要なファイル数分のforループ処理を作ってあげる。
$csv[$a..$b]
この方法でcsvの何行目から何行目まで抜き出すのかを指定し、出力処理を行う。
これで分割してファイルを出力できる。